Skip to content

Commit

Permalink
Merge pull request #9 from bastgau/develop
Browse files Browse the repository at this point in the history
Add new sensor, switch and update entities
  • Loading branch information
bastgau authored Mar 2, 2025
2 parents 084809f + 5b4f245 commit a5a23cb
Show file tree
Hide file tree
Showing 23 changed files with 709 additions and 78 deletions.
94 changes: 69 additions & 25 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,70 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "HA Pi-hole V6",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/python:1-3.12-bullseye",

"mounts": [
"type=bind,source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/vscode/.ssh,readonly"
]

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "pip3 install --user -r requirements.txt",

// Configure tool-specific properties.
// "customizations": {},

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
"name": "Pi-hole V6 Integration",
"image": "mcr.microsoft.com/devcontainers/python:dev-3.13",
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {
"installDirectlyFromGitHubRelease": true,
"version": "latest"
},
"ghcr.io/devcontainers/features/node:1": {
"nodeGypDependencies": true,
"version": "lts"
},
"ghcr.io/devcontainers-contrib/features/poetry:2": {
"version": "latest"
},
"ghcr.io/devcontainers/features/rust:1": {},
"ghcr.io/devcontainers-extra/features/apt-packages:1": {
"packages": [
"ffmpeg",
"libturbojpeg0",
"libpcap-dev"
]
}
},
"postCreateCommand": "scripts/setup",
"runArgs": [
"--network=host"
],
"forwardPorts": [
8123
],
"portsAttributes": {
"8123": {
"label": "Home Assistant",
"onAutoForward": "notify"
}
},
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"github.vscode-pull-request-github",
"ryanluker.vscode-coverage-gutters",
"ms-python.vscode-pylance",
"charliermarsh.ruff",
"ms-python.black-formatter"
],
"settings": {
"files.eol": "\n",
"editor.tabSize": 4,
"python.pythonPath": "/usr/bin/python3",
"python.analysis.autoSearchPaths": false,
"editor.formatOnPaste": false,
"editor.formatOnSave": true,
"editor.formatOnType": true,
"files.trimTrailingWhitespace": true,
"[markdown]": {
"files.trimTrailingWhitespace": false
},
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
}
}
}
}
},
"remoteUser": "vscode"
}
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto eol=lf
35 changes: 35 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: "Release"

on:
release:
types:
- "published"

permissions: {}

jobs:
release:
name: "Release"
runs-on: "ubuntu-latest"
permissions:
contents: write
steps:
- name: "Checkout the repository"
uses: "actions/checkout@v4"

- name: "Adjust version number"
shell: "bash"
run: |
yq -i -o json '.version="${{ github.event.release.tag_name }}"' \
"${{ github.workspace }}/custom_components/pi_hole_v6/manifest.json"
- name: "ZIP the integration directory"
shell: "bash"
run: |
cd "${{ github.workspace }}/custom_components/pi_hole_v6"
zip pi_hole_v6.zip -r ./
- name: "Upload the ZIP file to the release"
uses: softprops/action-gh-release@v2.2.1
with:
files: ${{ github.workspace }}/custom_components/pi_hole_v6/pi_hole_v6.zip
18 changes: 18 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# artifacts
__pycache__
.pytest*
*.egg-info
*/build/*
*/dist/*


# misc
.coverage
coverage.xml


# Home Assistant configuration
config/*
!config/configuration.yaml
.DS_Store
config/configuration.yaml
17 changes: 17 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Home Assistant",
"type": "debugpy",
"request": "launch",
"module": "homeassistant",
"justMyCode": false,
"args": [
"--debug",
"-c",
"config"
]
}
]
}
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"[python]": {
"_editor.defaultFormatter": "ms-python.black-formatter"
},
"python.formatting.provider": "none"
}
27 changes: 27 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Run Home Assistant on port 8123",
"type": "shell",
"command": "scripts/develop",
"problemMatcher": []
}
],
"configurations": [
{
// Example of attaching to local debug server
"name": "Python: Attach Local",
"type": "python",
"request": "attach",
"port": 5678,
"host": "localhost",
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "."
}
],
}
]
}
Binary file removed custom_components/pi_hole_v6/.DS_Store
Binary file not shown.
8 changes: 6 additions & 2 deletions custom_components/pi_hole_v6/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

from __future__ import annotations

from dataclasses import dataclass
import logging
from dataclasses import dataclass

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_NAME, CONF_PASSWORD, CONF_URL, Platform
Expand All @@ -23,7 +23,7 @@
Platform.BINARY_SENSOR,
Platform.SENSOR,
Platform.SWITCH,
# Platform.UPDATE,
Platform.UPDATE,
]

type PiHoleV6ConfigEntry = ConfigEntry[PiHoleV6Data]
Expand Down Expand Up @@ -59,6 +59,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: PiHoleV6ConfigEntry) ->
"DNS Queries Forwarded": "queries_forwarded",
"DNS Unique Clients": "unique_clients",
"DNS Unique Domains": "unique_domains",
"Remaining until blocking mode": "timer",
}

@callback
Expand Down Expand Up @@ -97,6 +98,9 @@ async def async_update_data() -> None:
if not isinstance(await api_client.call_padd(), dict):
raise ConfigEntryAuthFailed

if not isinstance(await api_client.call_get_groups(), dict):
raise ConfigEntryAuthFailed

coordinator = DataUpdateCoordinator(
hass,
_LOGGER,
Expand Down
90 changes: 88 additions & 2 deletions custom_components/pi_hole_v6/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
from socket import gaierror as GaiError
from typing import Any

from aiohttp import ClientError, ContentTypeError
import requests
from aiohttp import ClientError, ContentTypeError

from .exceptions import (
ClientConnectorException,
Expand All @@ -29,6 +29,7 @@ class API:
cache_blocking: dict[str, Any] = {}
cache_padd: dict[str, Any] = {}
cache_summary: dict[str, Any] = {}
cache_groups: dict[str, dict[str, Any]] = {}

url: str = ""

Expand Down Expand Up @@ -105,9 +106,11 @@ async def _call(
request: requests.Response

try:
async with asyncio.timeout(600):
async with asyncio.timeout(60):
if method.lower() == "post":
request = await self._session.post(url, json=data, headers=headers)
elif method.lower() == "put":
request = await self._session.put(url, json=data, headers=headers)
elif method.lower() == "delete":
request = await self._session.delete(url, headers=headers)
elif method.lower() == "get":
Expand Down Expand Up @@ -369,3 +372,86 @@ async def call_blocking_disabled(
"reason": result["reason"],
"data": result["data"],
}

async def call_get_groups(self) -> dict[str, Any]:
"""Retrieve the list of Pi-hole groups.
Returns:
result (dict[str, Any]): A dictionary with the keys "code", "reason", and "data".
"""

url: str = "/groups"

result: dict[str, Any] = await self._call(
url,
action="groups",
method="GET",
)

for group in result["data"]["groups"]:
self.cache_groups[group["name"]] = {
"name": group["name"],
"comment": group["comment"],
"enabled": group["enabled"],
}

return {
"code": result["code"],
"reason": result["reason"],
"data": result["data"],
}

async def call_group_disable(self, group: str) -> dict[str, Any]:
"""Disable Pi-hole group.
Returns:
result (dict[str, Any]): A dictionary with the keys "code", "reason", and "data".
"""

url: str = f"/groups/{group}"

result: dict[str, Any] = await self._call(
url,
action="group-disable",
method="PUT",
data={
"name": group,
"comment": self.cache_groups[group]["comment"],
"enabled": False,
},
)

return {
"code": result["code"],
"reason": result["reason"],
"data": result["data"],
}

async def call_group_enable(self, group: str) -> dict[str, Any]:
"""Enable Pi-hole group.
Returns:
result (dict[str, Any]): A dictionary with the keys "code", "reason", and "data".
"""

url: str = f"/groups/{group}"

result: dict[str, Any] = await self._call(
url,
action="group-disable",
method="PUT",
data={
"name": group,
"comment": self.cache_groups[group]["comment"],
"enabled": True,
},
)

return {
"code": result["code"],
"reason": result["reason"],
"data": result["data"],
}
Loading

0 comments on commit a5a23cb

Please sign in to comment.