Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions pydeconz/interfaces/config.py
Original file line number Diff line number Diff line change
@@ -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)
215 changes: 215 additions & 0 deletions pydeconz/models/config.py
Original file line number Diff line number Diff line change
@@ -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", {})