fix: minor fixes
Some checks failed
🧪 Integration Testing / 🔧 Test Integration (2025.9.4, 3.10) (push) Failing after 32s
🧪 Integration Testing / 🔧 Test Integration (2025.9.4, 3.11) (push) Failing after 14s
🧪 Integration Testing / 🔧 Test Integration (2025.9.4, 3.12) (push) Failing after 15s
🧪 Integration Testing / 🔧 Test Integration (2025.9.4, 3.13) (push) Failing after 1m57s
🧪 Integration Testing / 🔧 Test Integration (2025.9.4, 3.9) (push) Failing after 28s
🛡️ Code Quality & Security Check / 🔍 Code Quality Analysis (push) Failing after 19s
Some checks failed
🧪 Integration Testing / 🔧 Test Integration (2025.9.4, 3.10) (push) Failing after 32s
🧪 Integration Testing / 🔧 Test Integration (2025.9.4, 3.11) (push) Failing after 14s
🧪 Integration Testing / 🔧 Test Integration (2025.9.4, 3.12) (push) Failing after 15s
🧪 Integration Testing / 🔧 Test Integration (2025.9.4, 3.13) (push) Failing after 1m57s
🧪 Integration Testing / 🔧 Test Integration (2025.9.4, 3.9) (push) Failing after 28s
🛡️ Code Quality & Security Check / 🔍 Code Quality Analysis (push) Failing after 19s
Signed-off-by: Rafal Zielinski <sq4ind@gmail.com>
This commit is contained in:
@@ -12,8 +12,8 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: ['3.11', '3.12']
|
python-version: ['3.9','3.10','3.11','3.12','3.13']
|
||||||
home-assistant-version: ['2023.12.0', '2024.1.0']
|
home-assistant-version: ['2025.9.4']
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: 📥 Checkout Code
|
- name: 📥 Checkout Code
|
||||||
|
@@ -24,7 +24,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install flake8 black isort mypy bandit safety
|
pip install flake8 black isort mypy bandit safety
|
||||||
pip install homeassistant==2023.12.0
|
pip install homeassistant==2025.9.4
|
||||||
pip install -r requirements-dev.txt || echo "No dev requirements found"
|
pip install -r requirements-dev.txt || echo "No dev requirements found"
|
||||||
|
|
||||||
- name: 🎨 Check Code Formatting (Black)
|
- name: 🎨 Check Code Formatting (Black)
|
||||||
|
@@ -18,6 +18,7 @@ from .api import AdGuardHomeAPI
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"""Set up AdGuard Control Hub from a config entry."""
|
"""Set up AdGuard Control Hub from a config entry."""
|
||||||
session = async_get_clientsession(hass, entry.data.get(CONF_VERIFY_SSL, True))
|
session = async_get_clientsession(hass, entry.data.get(CONF_VERIFY_SSL, True))
|
||||||
@@ -34,8 +35,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
# Test the connection
|
# Test the connection
|
||||||
try:
|
try:
|
||||||
await api.test_connection()
|
await api.test_connection()
|
||||||
_LOGGER.info("Successfully connected to AdGuard Home at %s:%s",
|
_LOGGER.info("Successfully connected to AdGuard Home at %s:%s",
|
||||||
entry.data[CONF_HOST], entry.data[CONF_PORT])
|
entry.data[CONF_HOST], entry.data[CONF_PORT])
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
_LOGGER.error("Failed to connect to AdGuard Home: %s", err)
|
_LOGGER.error("Failed to connect to AdGuard Home: %s", err)
|
||||||
raise ConfigEntryNotReady(f"Unable to connect: {err}")
|
raise ConfigEntryNotReady(f"Unable to connect: {err}")
|
||||||
@@ -57,6 +58,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
_LOGGER.info("AdGuard Control Hub setup complete")
|
_LOGGER.info("AdGuard Control Hub setup complete")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"""Unload AdGuard Control Hub config entry."""
|
"""Unload AdGuard Control Hub config entry."""
|
||||||
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||||
@@ -66,6 +68,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
|
|
||||||
return unload_ok
|
return unload_ok
|
||||||
|
|
||||||
|
|
||||||
class AdGuardControlHubCoordinator(DataUpdateCoordinator):
|
class AdGuardControlHubCoordinator(DataUpdateCoordinator):
|
||||||
"""AdGuard Control Hub data update coordinator."""
|
"""AdGuard Control Hub data update coordinator."""
|
||||||
|
|
||||||
@@ -88,7 +91,7 @@ class AdGuardControlHubCoordinator(DataUpdateCoordinator):
|
|||||||
# Fetch all data concurrently for better performance
|
# Fetch all data concurrently for better performance
|
||||||
results = await asyncio.gather(
|
results = await asyncio.gather(
|
||||||
self.api.get_clients(),
|
self.api.get_clients(),
|
||||||
self.api.get_statistics(),
|
self.api.get_statistics(),
|
||||||
self.api.get_status(),
|
self.api.get_status(),
|
||||||
return_exceptions=True,
|
return_exceptions=True,
|
||||||
)
|
)
|
||||||
@@ -103,7 +106,7 @@ class AdGuardControlHubCoordinator(DataUpdateCoordinator):
|
|||||||
|
|
||||||
# Update stored data (use empty dict if fetch failed)
|
# Update stored data (use empty dict if fetch failed)
|
||||||
self._clients = {
|
self._clients = {
|
||||||
client["name"]: client
|
client["name"]: client
|
||||||
for client in (clients.get("clients", []) if not isinstance(clients, Exception) else [])
|
for client in (clients.get("clients", []) if not isinstance(clients, Exception) else [])
|
||||||
}
|
}
|
||||||
self._statistics = statistics if not isinstance(statistics, Exception) else {}
|
self._statistics = statistics if not isinstance(statistics, Exception) else {}
|
||||||
@@ -123,7 +126,7 @@ class AdGuardControlHubCoordinator(DataUpdateCoordinator):
|
|||||||
"""Return clients data."""
|
"""Return clients data."""
|
||||||
return self._clients
|
return self._clients
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def statistics(self):
|
def statistics(self):
|
||||||
"""Return statistics data."""
|
"""Return statistics data."""
|
||||||
return self._statistics
|
return self._statistics
|
||||||
@@ -131,4 +134,4 @@ class AdGuardControlHubCoordinator(DataUpdateCoordinator):
|
|||||||
@property
|
@property
|
||||||
def protection_status(self):
|
def protection_status(self):
|
||||||
"""Return protection status data."""
|
"""Return protection status data."""
|
||||||
return self._protection_status
|
return self._protection_status
|
||||||
|
@@ -7,11 +7,12 @@ from .const import API_ENDPOINTS
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class AdGuardHomeAPI:
|
class AdGuardHomeAPI:
|
||||||
"""API wrapper for AdGuard Home."""
|
"""API wrapper for AdGuard Home."""
|
||||||
|
|
||||||
def __init__(self, host: str, port: int = 3000, username: str = None,
|
def __init__(self, host: str, port: int = 3000, username: str = None,
|
||||||
password: str = None, ssl: bool = False, session = None):
|
password: str = None, ssl: bool = False, session=None):
|
||||||
self.host = host
|
self.host = host
|
||||||
self.port = port
|
self.port = port
|
||||||
self.username = username
|
self.username = username
|
||||||
@@ -88,7 +89,8 @@ class AdGuardHomeAPI:
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def update_client_blocked_services(self, client_name: str, blocked_services: list, schedule: dict = None) -> dict:
|
async def update_client_blocked_services(self, client_name: str, blocked_services: list,
|
||||||
|
schedule: dict = None) -> dict:
|
||||||
"""Update blocked services for a specific client."""
|
"""Update blocked services for a specific client."""
|
||||||
client = await self.get_client_by_name(client_name)
|
client = await self.get_client_by_name(client_name)
|
||||||
if not client:
|
if not client:
|
||||||
@@ -139,4 +141,4 @@ class AdGuardHomeAPI:
|
|||||||
elif not enabled and service_id in service_ids:
|
elif not enabled and service_id in service_ids:
|
||||||
service_ids.remove(service_id)
|
service_ids.remove(service_id)
|
||||||
|
|
||||||
return await self.update_client_blocked_services(client_name, service_ids)
|
return await self.update_client_blocked_services(client_name, service_ids)
|
||||||
|
@@ -1,13 +1,12 @@
|
|||||||
{
|
{
|
||||||
"domain": "adguard_hub",
|
"domain": "adguard_hub",
|
||||||
"name": "AdGuard Control Hub",
|
"name": "AdGuard Control Hub",
|
||||||
"codeowners": ["@your-gitea-username"],
|
"codeowners": ["@sq4ind"],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"documentation": "https://your-gitea-domain.com/your-username/adguard-control-hub",
|
"documentation": "https://git.sq4ind.eu/sq4ind/adguard-control-hub",
|
||||||
"integration_type": "hub",
|
"integration_type": "hub",
|
||||||
"iot_class": "local_polling",
|
"iot_class": "local_polling",
|
||||||
"issue_tracker": "https://your-gitea-domain.com/your-username/adguard-control-hub/issues",
|
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"aiohttp>=3.8.0"
|
"aiohttp>=3.8.0"
|
||||||
],
|
],
|
||||||
|
@@ -11,6 +11,7 @@ from .const import DOMAIN, ICON_PROTECTION, ICON_PROTECTION_OFF, ICON_CLIENT, MA
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback):
|
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback):
|
||||||
"""Set up AdGuard Control Hub switch platform."""
|
"""Set up AdGuard Control Hub switch platform."""
|
||||||
coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"]
|
coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"]
|
||||||
@@ -26,6 +27,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry, asyn
|
|||||||
|
|
||||||
async_add_entities(entities)
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
|
||||||
class AdGuardBaseSwitch(CoordinatorEntity, SwitchEntity):
|
class AdGuardBaseSwitch(CoordinatorEntity, SwitchEntity):
|
||||||
"""Base class for AdGuard switches."""
|
"""Base class for AdGuard switches."""
|
||||||
|
|
||||||
@@ -39,6 +41,7 @@ class AdGuardBaseSwitch(CoordinatorEntity, SwitchEntity):
|
|||||||
"model": "AdGuard Home",
|
"model": "AdGuard Home",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class AdGuardProtectionSwitch(AdGuardBaseSwitch):
|
class AdGuardProtectionSwitch(AdGuardBaseSwitch):
|
||||||
"""Switch to control global AdGuard protection."""
|
"""Switch to control global AdGuard protection."""
|
||||||
|
|
||||||
@@ -63,6 +66,7 @@ class AdGuardProtectionSwitch(AdGuardBaseSwitch):
|
|||||||
await self.api.set_protection(False)
|
await self.api.set_protection(False)
|
||||||
await self.coordinator.async_request_refresh()
|
await self.coordinator.async_request_refresh()
|
||||||
|
|
||||||
|
|
||||||
class AdGuardClientSwitch(AdGuardBaseSwitch):
|
class AdGuardClientSwitch(AdGuardBaseSwitch):
|
||||||
"""Switch to control client-specific protection."""
|
"""Switch to control client-specific protection."""
|
||||||
|
|
||||||
@@ -86,4 +90,4 @@ class AdGuardClientSwitch(AdGuardBaseSwitch):
|
|||||||
async def async_turn_off(self, **kwargs):
|
async def async_turn_off(self, **kwargs):
|
||||||
# This would update client settings - simplified for basic functionality
|
# This would update client settings - simplified for basic functionality
|
||||||
_LOGGER.info("Would disable protection for %s", self.client_name)
|
_LOGGER.info("Would disable protection for %s", self.client_name)
|
||||||
await self.coordinator.async_request_refresh()
|
await self.coordinator.async_request_refresh()
|
||||||
|
Reference in New Issue
Block a user