diff --git a/changelog.txt b/changelog.txt index 88fef4a8..fce98b54 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,10 @@ -Version 0.17.1 (2022-01-09) +Version 0.18.0 (2022-01-09) - Add config option to specify storage directory +- Move Exceptions to own module +- Add binary_sensor platform for SVs +- Add config check +- Add hub_entities_by_platform +- Remove option_enable_sensors_for_system_variables Version 0.17.1 (2022-01-09) - Fix naming for multi channel custom entities diff --git a/hahomematic/central_unit.py b/hahomematic/central_unit.py index 039b6f29..c4f78851 100644 --- a/hahomematic/central_unit.py +++ b/hahomematic/central_unit.py @@ -41,6 +41,7 @@ from hahomematic.decorators import callback_system_event from hahomematic.device import HmDevice, create_devices from hahomematic.entity import BaseEntity, GenericEntity +from hahomematic.exceptions import HaHomematicException, NoConnection import hahomematic.helpers from hahomematic.helpers import ( check_or_create_directory, @@ -49,7 +50,6 @@ ) from hahomematic.hub import HmDummyHub, HmHub from hahomematic.json_rpc_client import JsonRpcAioHttpClient -from hahomematic.xml_rpc_proxy import NoConnection import hahomematic.xml_rpc_server as xml_rpc _LOGGER = logging.getLogger(__name__) @@ -115,10 +115,7 @@ def create_hub(self) -> HmHub | HmDummyHub: if self.model is BACKEND_PYDEVCCU: hub = HmDummyHub(central=self) else: - hub = HmHub( - central=self, - use_entities=self.central_config.option_enable_sensors_for_system_variables, - ) + hub = HmHub(central=self) return hub async def init_hub(self) -> None: @@ -600,7 +597,6 @@ def __init__( callback_host: str | None = None, callback_port: int | None = None, json_port: int | None = None, - option_enable_sensors_for_system_variables: bool = False, ): self.loop = loop self.xml_rpc_server = xml_rpc_server @@ -616,9 +612,6 @@ def __init__( self.callback_host = callback_host self.callback_port = callback_port self.json_port = json_port - self.option_enable_sensors_for_system_variables = ( - option_enable_sensors_for_system_variables - ) @property def device_url(self) -> str: @@ -631,6 +624,14 @@ def device_url(self) -> str: url = f"{url}:{self.json_port}" return f"{url}" + def check_config(self) -> bool: + """Check config.""" + try: + check_or_create_directory(self.storage_folder) + except HaHomematicException: + return False + return True + async def get_central(self) -> CentralUnit: """Identify the used client.""" central = CentralUnit(self) diff --git a/hahomematic/client.py b/hahomematic/client.py index d1ee4432..945523f0 100644 --- a/hahomematic/client.py +++ b/hahomematic/client.py @@ -31,9 +31,10 @@ RELEVANT_PARAMSETS, ) from hahomematic.device import HmDevice +from hahomematic.exceptions import NoConnection, ProxyException from hahomematic.helpers import build_api_url, get_local_ip, parse_ccu_sys_var from hahomematic.json_rpc_client import JsonRpcAioHttpClient -from hahomematic.xml_rpc_proxy import NoConnection, ProxyException, XmlRpcProxy +from hahomematic.xml_rpc_proxy import XmlRpcProxy _LOGGER = logging.getLogger(__name__) diff --git a/hahomematic/const.py b/hahomematic/const.py index 2e3be8d7..50779b03 100644 --- a/hahomematic/const.py +++ b/hahomematic/const.py @@ -296,7 +296,8 @@ class HmPlatform(Enum): CLIMATE = "climate" COVER = "cover" EVENT = "event" - HUB = "hub" + HUB_SENSOR = "hub_sensor" + HUB_BINARY_SENSOR = "hub_binary_sensor" LIGHT = "light" LOCK = "lock" NUMBER = "number" diff --git a/hahomematic/exceptions.py b/hahomematic/exceptions.py index d3b7e4ed..4434a325 100644 --- a/hahomematic/exceptions.py +++ b/hahomematic/exceptions.py @@ -1,5 +1,14 @@ """Module for HaHomematicExceptions.""" +from __future__ import annotations class HaHomematicException(Exception): """hahomematic exception.""" + + +class ProxyException(HaHomematicException): + """hahomematic Proxy exception.""" + + +class NoConnection(HaHomematicException): + """hahomematic NoConnection exception.""" diff --git a/hahomematic/helpers.py b/hahomematic/helpers.py index 81ba5712..e03563e2 100644 --- a/hahomematic/helpers.py +++ b/hahomematic/helpers.py @@ -21,6 +21,7 @@ ATTR_VALUE, ) import hahomematic.devices.entity_definition as hm_entity_definition +from hahomematic.exceptions import HaHomematicException _LOGGER = logging.getLogger(__name__) @@ -101,7 +102,7 @@ def check_or_create_directory(directory: str) -> bool: directory, ose.strerror, ) - return False + raise HaHomematicException from ose return True diff --git a/hahomematic/hub.py b/hahomematic/hub.py index 8b6931bc..0454a298 100644 --- a/hahomematic/hub.py +++ b/hahomematic/hub.py @@ -8,7 +8,7 @@ from typing import Any import hahomematic.central_unit as hm_central -from hahomematic.const import BACKEND_CCU, INIT_DATETIME, HmPlatform +from hahomematic.const import BACKEND_CCU, INIT_DATETIME, HmEntityUsage, HmPlatform from hahomematic.helpers import generate_unique_id _LOGGER = logging.getLogger(__name__) @@ -48,7 +48,6 @@ def __init__( self._remove_callbacks: list[Callable] = [] self.create_in_ha: bool = True self.should_poll = False - self.platform = HmPlatform.HUB @property def available(self) -> bool: @@ -136,6 +135,7 @@ def __init__(self, central: hm_central.CentralUnit, name: str, value: Any): parameter=name, prefix="hub", ) + self.usage = HmEntityUsage.ENTITY super().__init__(central=central, unique_id=unique_id, name=name, value=value) @property @@ -145,6 +145,13 @@ def device_info(self) -> dict[str, str] | None: return self._hub.device_info return None + @property + def platform(self) -> HmPlatform: + """Return the platform.""" + if isinstance(self.value, bool): + return HmPlatform.HUB_BINARY_SENSOR + return HmPlatform.HUB_SENSOR + async def set_value(self, value: Any) -> None: """Set variable value on CCU/Homegear.""" old_value = self._value @@ -165,7 +172,7 @@ async def set_value(self, value: Any) -> None: class HmHub(BaseHubEntity): """The HomeMatic hub. (CCU/HomeGear).""" - def __init__(self, central: hm_central.CentralUnit, use_entities: bool = False): + def __init__(self, central: hm_central.CentralUnit): """Initialize HomeMatic hub.""" unique_id: str = generate_unique_id( domain=central.domain, @@ -177,7 +184,6 @@ def __init__(self, central: hm_central.CentralUnit, use_entities: bool = False): super().__init__(central, unique_id, name) self.hub_entities: dict[str, HmSystemVariable] = {} self._variables: dict[str, Any] = {} - self._use_entities = use_entities self.should_poll = True @property @@ -190,6 +196,17 @@ def extra_state_attributes(self) -> dict[str, Any]: """Return the state attributes.""" return self._variables.copy() + @property + def hub_entities_by_platform(self) -> dict[HmPlatform, list[HmSystemVariable]]: + """Return the system variables by platform""" + sysvars: dict[HmPlatform, list[HmSystemVariable]] = {} + for entity in self.hub_entities.values(): + if entity.platform not in sysvars: + sysvars[entity.platform] = [] + sysvars[entity.platform].append(entity) + + return sysvars + async def fetch_data(self) -> None: """fetch data for the hub.""" await self._update_hub_state() @@ -219,7 +236,7 @@ async def _update_entities(self) -> None: variables = _clean_variables(variables) for name, value in variables.items(): - if not self._use_entities or _is_excluded(name, EXCLUDED_FROM_SENSOR): + if _is_excluded(name, EXCLUDED_FROM_SENSOR): self._variables[name] = value continue @@ -242,8 +259,11 @@ async def _update_entities(self) -> None: def _create_system_variable(self, name: str, value: Any) -> None: """Create system variable as entity.""" - variable = HmSystemVariable(central=self._central, name=name, value=value) - self.hub_entities[name] = variable + self.hub_entities[name] = HmSystemVariable( + central=self._central, + name=f"{self._central.instance_name} {name}", + value=value, + ) async def set_system_variable(self, name: str, value: Any) -> None: """Set variable value on CCU/Homegear.""" @@ -257,7 +277,7 @@ async def set_system_variable(self, name: str, value: Any) -> None: class HmDummyHub(BaseHubEntity): """The HomeMatic hub. (CCU/HomeGear).""" - def __init__(self, central: hm_central.CentralUnit, use_entities: bool = False): + def __init__(self, central: hm_central.CentralUnit): """Initialize HomeMatic hub.""" unique_id: str = generate_unique_id( domain=central.domain, @@ -268,7 +288,6 @@ def __init__(self, central: hm_central.CentralUnit, use_entities: bool = False): name: str = central.instance_name super().__init__(central, unique_id, name) self.hub_entities: dict[str, BaseHubEntity] = {} - self._use_entities = use_entities @property def device_info(self) -> dict[str, Any]: @@ -280,6 +299,11 @@ def extra_state_attributes(self) -> dict[str, Any]: """Return the state attributes.""" return {} + @property + def hub_entities_by_platform(self) -> dict[HmPlatform, list[HmSystemVariable]]: + """Return the system variables by platform""" + return {} + async def fetch_data(self) -> None: """do not fetch data for the hub.""" return diff --git a/hahomematic/xml_rpc_proxy.py b/hahomematic/xml_rpc_proxy.py index 1198c954..02eca621 100644 --- a/hahomematic/xml_rpc_proxy.py +++ b/hahomematic/xml_rpc_proxy.py @@ -11,6 +11,7 @@ import xmlrpc.client from hahomematic.const import ATTR_TLS, ATTR_VERIFY_TLS +from hahomematic.exceptions import NoConnection, ProxyException from hahomematic.helpers import get_tls_context _LOGGER = logging.getLogger(__name__) @@ -19,14 +20,6 @@ ATTR_ENCODING_ISO_8859_1 = "ISO-8859-1" -class ProxyException(Exception): - """hahomematic Proxy exception.""" - - -class NoConnection(Exception): - """hahomematic NoConnection exception.""" - - # noinspection PyProtectedMember,PyUnresolvedReferences class XmlRpcProxy(xmlrpc.client.ServerProxy): """ diff --git a/setup.py b/setup.py index 47d0ac14..0bafbd0c 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ def readme(): }, PACKAGE_NAME = "hahomematic" HERE = os.path.abspath(os.path.dirname(__file__)) -VERSION = "0.17.2" +VERSION = "0.18.0" PACKAGES = find_packages(exclude=["tests", "tests.*", "dist", "build"])