From 0366eecb67af29121bb52c536fedf9bb4ee1cb03 Mon Sep 17 00:00:00 2001 From: Robert Svensson Date: Mon, 28 Mar 2022 22:08:11 +0200 Subject: [PATCH] Move config to new structure --- pydeconz/interfaces/config.py | 100 ++++++++++++++++ pydeconz/models/config.py | 215 ++++++++++++++++++++++++++++++++++ 2 files changed, 315 insertions(+) create mode 100644 pydeconz/interfaces/config.py create mode 100644 pydeconz/models/config.py diff --git a/pydeconz/interfaces/config.py b/pydeconz/interfaces/config.py new file mode 100644 index 00000000..9941ebc1 --- /dev/null +++ b/pydeconz/interfaces/config.py @@ -0,0 +1,100 @@ +"""Python library to connect deCONZ and Home Assistant to work together.""" + +from __future__ import annotations + +from typing import Any, Literal + +from ..models import ResourceGroup +from ..models.config import Config as ConfigModel +from .api import APIItems + + +class Config(APIItems[ConfigModel]): + """Manager of deCONZ gateway configuration.""" + + item_cls = ConfigModel + resource_group = ResourceGroup.CONFIG + + async def set_config( + self, + discovery: bool | None = None, + group_delay: int | None = None, + light_last_seen_interval: int | None = None, + name: str | None = None, + network_open_duration: int | None = None, + otau_active: bool | None = None, + permit_join: int | None = None, + rf_connected: bool | None = None, + time_format: Literal["12h", "24h"] | None = None, + time_zone: str | None = None, + unlock: int | None = None, + update_channel: Literal["alpha", "beta", "stable"] | None = None, + utc: str | None = None, + zigbee_channel: Literal[11, 15, 20, 25] | None = None, + websocket_notify_all: bool | None = None, + ) -> dict[str, Any]: + """Modify configuration parameters. + + Supported values: + - discovery [bool] + Set gateway discovery over the internet active or inactive. + - group_delay [int] 0-5000 + Time between two group commands in milliseconds. + - light_last_seen_interval [int] 1-65535 default 60 + Sets the number of seconds where the timestamp for "lastseen" + is updated at the earliest for light resources. For any such update, + a seperate websocket event will be triggered. + - name [str] 0-16 characters + Name of the gateway. + - network_open_duration [int] 1-65535 + Sets the lights and sensors search duration in seconds. + - otau_active [bool] + Set OTAU active or inactive + - permit_join [int] 0-255 + Open the network so that other zigbee devices can join. + 0 = network closed + 255 = network open + 1–254 = time in seconds the network remains open + The value will decrement automatically. + - rf_connected [bool] + Set to true to bring the Zigbee network up and false to bring it down. + This has the same effect as using the Join and Leave buttons in deCONZ. + - time_format [str] 12h|24h + Can be used to store the timeformat permanently. + - time_zone [str] + Set the timezone of the gateway (only on Raspberry Pi). + - unlock [int] 0-600 (seconds) + Unlock the gateway so that apps can register themselves to the gateway. + - update_channel [str] stable|alpha|beta + Set update channel. + - utc [str] + Set the UTC time of the gateway (only on Raspbery Pi) + in ISO 8601 format (yyyy-MM-ddTHH:mm:ss). + - zigbee_channel [int] 11|15|20|25 + Set the zigbeechannel of the gateway. + Notify other Zigbee devices also to change their channel. + - websocket_notify_all [bool] default True + When true all state changes will be signalled through the websocket connection. + """ + data = { + key: value + for key, value in { + "discovery": discovery, + "groupdelay": group_delay, + "lightlastseeninterval": light_last_seen_interval, + "name": name, + "networkopenduration": network_open_duration, + "otauactive": otau_active, + "permitjoin": permit_join, + "rfconnected": rf_connected, + "timeformat": time_format, + "timezone": time_zone, + "unlock": unlock, + "updatechannel": update_channel, + "utc": utc, + "zigbeechannel": zigbee_channel, + "websocketnotifyall": websocket_notify_all, + }.items() + if value is not None + } + return await self.gateway.request("put", path="/config", json=data) diff --git a/pydeconz/models/config.py b/pydeconz/models/config.py new file mode 100644 index 00000000..d629fb2d --- /dev/null +++ b/pydeconz/models/config.py @@ -0,0 +1,215 @@ +"""Python library to connect deCONZ and Home Assistant to work together.""" + +from __future__ import annotations + +from typing import Any, Final, Literal, TypedDict + +from ..utils import normalize_bridge_id +from .api import APIItem + +UNINITIALIZED_BRIDGE_ID: Final = "0000000000000000" + + +class TypedConfig(TypedDict): + """Config type definition.""" + + apiversion: str + backup: dict[str, Any] + bridgeid: str + datastoreversion: str + devicename: str + dhcp: bool + factorynew: bool + fwversion: str + gateway: str + internetservices: dict[str, Any] + ipaddress: str + lightlastseeninterval: int + linkbutton: bool + localtime: str + mac: str + modelid: str + name: str + netmask: str + networkopenduration: int + ntp: Literal["synced", "unsynced"] + panid: int + portalservices: bool + portalstate: dict[str, Any] + proxyaddress: str + proxyport: int + replacesbridgeid: str + rfconnected: bool + starterkitid: str + swupdate: dict[str, Any] + swupdate2: dict[str, Any] + swversion: str + timeformat: Literal["12h", "24h"] + timezone: str + UTC: str + uuid: str + websocketnotifyall: bool + websocketport: int + whitelist: dict[str, dict[str, str]] + zigbeechannel: int + + +class Config(APIItem): + """Config class.""" + + raw: TypedConfig + + @property + def api_version(self) -> str | None: + """Version of the deCONZ Rest API.""" + return self.raw.get("apiversion") + + @property + def bridge_id(self) -> str: + """Gateway unique identifier.""" + return normalize_bridge_id(self.raw.get("bridgeid", UNINITIALIZED_BRIDGE_ID)) + + @property + def device_name(self) -> str | None: + """Product name of the gateway. + + Valid values are "ConBee", "RaspBee", "ConBee II" and "RaspBee II". + """ + return self.raw.get("devicename") + + @property + def dhcp(self) -> bool | None: + """Whether the IP address of the bridge is obtained with DHCP.""" + return self.raw.get("dhcp") + + @property + def firmware_version(self) -> str | None: + """Version of the ZigBee firmware.""" + return self.raw.get("fwversion") + + @property + def gateway(self) -> str | None: + """IPv4 address of the gateway.""" + return self.raw.get("gateway") + + @property + def ip_address(self) -> str | None: + """IPv4 address of the gateway.""" + return self.raw.get("ipaddress") + + @property + def link_button(self) -> bool | None: + """Is gateway unlocked.""" + return self.raw.get("linkbutton") + + @property + def local_time(self) -> str | None: + """Localtime of the gateway.""" + return self.raw.get("localtime") + + @property + def mac(self) -> str | None: + """MAC address of gateway.""" + return self.raw.get("mac") + + @property + def model_id(self) -> str | None: + """Model describing either conbee or raspbee.""" + return self.raw.get("modelid") + + @property + def name(self) -> str | None: + """Name of the gateway.""" + return self.raw.get("name") + + @property + def network_mask(self) -> str | None: + """Network mask of the gateway.""" + return self.raw.get("netmask") + + @property + def network_open_duration(self) -> int | None: + """Duration in seconds used by lights and sensors search.""" + return self.raw.get("networkopenduration") + + @property + def ntp(self) -> Literal["synced", "unsynced"] | None: + """Tells if the NTP time is "synced" or "unsynced". + + Only for gateways running on Linux. + """ + return self.raw.get("ntp") + + @property + def pan_id(self) -> int | None: + """Zigbee pan ID of the gateway.""" + return self.raw.get("panid") + + @property + def portal_services(self) -> bool | None: + """State of registration to portal service. + + Is the bridge registered to synchronize data with a portal account. + """ + return self.raw.get("portalservices") + + @property + def rf_connected(self) -> bool | None: + """State of deCONZ connection to firmware and if Zigbee network is up.""" + return self.raw.get("rfconnected") + + @property + def software_update(self) -> dict[str, Any]: + """Contains information related to software updates.""" + return self.raw.get("swupdate", {}) + + @property + def software_version(self) -> str | None: + """Software version of the gateway.""" + return self.raw.get("swversion") + + @property + def time_format(self) -> Literal["12h", "24h"] | None: + """Timeformat used by gateway. + + Supported values: + "12h" or "24h" + """ + return self.raw.get("timeformat") + + @property + def time_zone(self) -> str | None: + """Time zone used by gateway. + + Only on Raspberry Pi. + "None" if not further specified. + """ + return self.raw.get("timezone") + + @property + def utc(self) -> str | None: + """UTC time of gateway in ISO 8601 format.""" + return self.raw.get("UTC") + + @property + def uuid(self) -> str | None: + """UPNP Unique ID of the gateway.""" + return self.raw.get("uuid") + + @property + def websocket_notify_all(self) -> bool | None: + """All state changes will be signalled through the Websocket connection. + + Default true. + """ + return self.raw.get("websocketnotifyall") + + @property + def websocket_port(self) -> int | None: + """Websocket port.""" + return self.raw.get("websocketport") + + @property + def whitelist(self) -> dict[str, Any]: + """Array of whitelisted API keys.""" + return self.raw.get("whitelist", {})