finish up entities

This commit is contained in:
rooba 2022-11-28 02:48:43 -08:00
parent 353adfddd2
commit 72a98b8541
4 changed files with 223 additions and 89 deletions

@ -3,6 +3,7 @@ __all__ = ("Router", "route", "RouterMeta", "SubRouter", "HughApi")
from inspect import signature from inspect import signature
from re import compile from re import compile
from typing import Any, Literal, Optional from typing import Any, Literal, Optional
from uuid import UUID
from httpx import AsyncClient from httpx import AsyncClient
from httpx._urls import URL as _URL from httpx._urls import URL as _URL
@ -58,8 +59,10 @@ def ret_cls(cls):
kwargs.pop("base_uri", None) kwargs.pop("base_uri", None)
ret = (await fn(self, *args, **kwargs)).json().get("data", []) ret = (await fn(self, *args, **kwargs)).json().get("data", [])
_rets = [] _rets = []
if isinstance(ret, list): if isinstance(ret, list):
for r in ret: for r in ret:
print(r)
_rets.append(cls(**r)) _rets.append(cls(**r))
else: else:
return cls(**ret) return cls(**ret)
@ -263,17 +266,17 @@ class HughApi(SubRouter):
@ret_cls(models.Scene) @ret_cls(models.Scene)
@route("GET", "/resource/scene/{scene_id}") @route("GET", "/resource/scene/{scene_id}")
async def get_scene(self, scene_id: str): async def get_scene(self, scene_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/scene/{scene_id}") @route("PUT", "/resource/scene/{scene_id}")
async def set_scene(self, scene_id: str, **kwargs): async def set_scene(self, scene_id: UUID, **kwargs):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("DELETE", "/resource/scene/{scene_id}") @route("DELETE", "/resource/scene/{scene_id}")
async def delete_scene(self, scene_id: str): async def delete_scene(self, scene_id: UUID):
... ...
@ret_cls(models.Room) @ret_cls(models.Room)
@ -288,17 +291,22 @@ class HughApi(SubRouter):
@ret_cls(models.Room) @ret_cls(models.Room)
@route("GET", "/resource/room/{room_id}") @route("GET", "/resource/room/{room_id}")
async def get_room(self, room_id: str): async def get_room(self, room_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/room/{room_id}") @route("PUT", "/resource/room/{room_id}")
async def set_room(self, room_id: str, **kwargs): async def set_room(
self,
room_id: UUID,
metadata: Optional[dict[str, str]] = None,
children: Optional[models._Identifier] = None,
):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("DELETE", "/resource/room/{room_id}") @route("DELETE", "/resource/room/{room_id}")
async def delete_room(self, room_id: str): async def delete_room(self, room_id: UUID):
... ...
@ret_cls(models.Zone) @ret_cls(models.Zone)
@ -313,17 +321,17 @@ class HughApi(SubRouter):
@ret_cls(models.Zone) @ret_cls(models.Zone)
@route("GET", "/resource/zone/{zone_id}") @route("GET", "/resource/zone/{zone_id}")
async def get_zone(self, zone_id: str): async def get_zone(self, zone_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/zone/{zone_id}") @route("PUT", "/resource/zone/{zone_id}")
async def set_zone(self, zone_id: str, **kwargs): async def set_zone(self, zone_id: UUID, **kwargs):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("DELETE", "/resource/zone/{zone_id}") @route("DELETE", "/resource/zone/{zone_id}")
async def delete_zone(self, zone_id: str): async def delete_zone(self, zone_id: UUID):
... ...
@ret_cls(models.BridgeHome) @ret_cls(models.BridgeHome)
@ -333,12 +341,12 @@ class HughApi(SubRouter):
@ret_cls(models.BridgeHome) @ret_cls(models.BridgeHome)
@route("GET", "/resource/bridge_home/{bridge_home_id}") @route("GET", "/resource/bridge_home/{bridge_home_id}")
async def get_bridge_home(self, bridge_home_id: str): async def get_bridge_home(self, bridge_home_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/bridge_home/{bridge_home_id}") @route("PUT", "/resource/bridge_home/{bridge_home_id}")
async def set_bridge_home(self, bridge_home_id: str, **kwargs): async def set_bridge_home(self, bridge_home_id: UUID, **kwargs):
... ...
@ret_cls(models.GroupedLight) @ret_cls(models.GroupedLight)
@ -348,12 +356,12 @@ class HughApi(SubRouter):
@ret_cls(models.GroupedLight) @ret_cls(models.GroupedLight)
@route("GET", "/resource/grouped_light/{grouped_light_id}") @route("GET", "/resource/grouped_light/{grouped_light_id}")
async def get_grouped_light(self, grouped_light_id: str): async def get_grouped_light(self, grouped_light_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/grouped_light/{grouped_light_id}") @route("PUT", "/resource/grouped_light/{grouped_light_id}")
async def set_grouped_light(self, grouped_light_id: str, **kwargs): async def set_grouped_light(self, grouped_light_id: UUID, **kwargs):
... ...
@ret_cls(models.Device) @ret_cls(models.Device)
@ -363,12 +371,12 @@ class HughApi(SubRouter):
@ret_cls(models.Device) @ret_cls(models.Device)
@route("GET", "/resource/device/{device_id}") @route("GET", "/resource/device/{device_id}")
async def get_device(self, device_id: str): async def get_device(self, device_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/device/{device_id}") @route("PUT", "/resource/device/{device_id}")
async def set_device(self, device_id: str, **kwargs): async def set_device(self, device_id: UUID, **kwargs):
... ...
@ret_cls(models.Bridge) @ret_cls(models.Bridge)
@ -378,12 +386,12 @@ class HughApi(SubRouter):
@ret_cls(models.Bridge) @ret_cls(models.Bridge)
@route("GET", "/resource/bridges/{bridge_id}") @route("GET", "/resource/bridges/{bridge_id}")
async def get_bridge(self, bridge_id: str): async def get_bridge(self, bridge_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/bridges/{bridge_id}") @route("PUT", "/resource/bridges/{bridge_id}")
async def set_bridge(self, bridge_id: str, **kwargs): async def set_bridge(self, bridge_id: UUID, **kwargs):
... ...
@ret_cls(models.DevicePower) @ret_cls(models.DevicePower)
@ -393,12 +401,12 @@ class HughApi(SubRouter):
@ret_cls(models.DevicePower) @ret_cls(models.DevicePower)
@route("GET", "/resource/device_power/{device_power_id}") @route("GET", "/resource/device_power/{device_power_id}")
async def get_device_power(self, device_power_id: str): async def get_device_power(self, device_power_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/device_power/{device_power_id}") @route("PUT", "/resource/device_power/{device_power_id}")
async def set_device_power(self, device_power_id: str, **kwargs): async def set_device_power(self, device_power_id: UUID, **kwargs):
... ...
@ret_cls(models.ZigbeeConnectivity) @ret_cls(models.ZigbeeConnectivity)
@ -408,12 +416,12 @@ class HughApi(SubRouter):
@ret_cls(models.ZigbeeConnectivity) @ret_cls(models.ZigbeeConnectivity)
@route("GET", "/resource/zigbee_connectivity/{zigbee_connectivity_id}") @route("GET", "/resource/zigbee_connectivity/{zigbee_connectivity_id}")
async def get_zigbee_connectivity(self, zigbee_connectivity_id: str): async def get_zigbee_connectivity(self, zigbee_connectivity_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/zigbee_connectivity/{zigbee_connectivity_id}") @route("PUT", "/resource/zigbee_connectivity/{zigbee_connectivity_id}")
async def set_zigbee_connectivity(self, zigbee_connectivity_id: str, **kwargs): async def set_zigbee_connectivity(self, zigbee_connectivity_id: UUID, **kwargs):
... ...
@ret_cls(models.ZGPConnectivity) @ret_cls(models.ZGPConnectivity)
@ -423,12 +431,12 @@ class HughApi(SubRouter):
@ret_cls(models.ZGPConnectivity) @ret_cls(models.ZGPConnectivity)
@route("GET", "/resource/zgb_connectivity/{zgb_connectivity_id}") @route("GET", "/resource/zgb_connectivity/{zgb_connectivity_id}")
async def get_zgb_connectivity(self, zgb_connectivity_id: str): async def get_zgb_connectivity(self, zgb_connectivity_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/zgb_connectivity/{zgb_connectivity_id}") @route("PUT", "/resource/zgb_connectivity/{zgb_connectivity_id}")
async def set_zgb_connectivity(self, zgb_connectivity_id: str, **kwargs): async def set_zgb_connectivity(self, zgb_connectivity_id: UUID, **kwargs):
... ...
@ret_cls(models.Motion) @ret_cls(models.Motion)
@ -438,12 +446,12 @@ class HughApi(SubRouter):
@ret_cls(models.Motion) @ret_cls(models.Motion)
@route("GET", "/resource/motion/{motion_id}") @route("GET", "/resource/motion/{motion_id}")
async def get_motion(self, motion_id: str): async def get_motion(self, motion_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/motion/{motion_id}") @route("PUT", "/resource/motion/{motion_id}")
async def set_motion(self, motion_id: str, **kwargs): async def set_motion(self, motion_id: UUID, **kwargs):
... ...
@ret_cls(models.Temperature) @ret_cls(models.Temperature)
@ -453,12 +461,12 @@ class HughApi(SubRouter):
@ret_cls(models.Temperature) @ret_cls(models.Temperature)
@route("GET", "/resource/temperature/{temperature_id}") @route("GET", "/resource/temperature/{temperature_id}")
async def get_temperature(self, temperature_id: str): async def get_temperature(self, temperature_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/temperature/{temperature_id}") @route("PUT", "/resource/temperature/{temperature_id}")
async def set_temperature(self, temperature_id: str, **kwargs): async def set_temperature(self, temperature_id: UUID, **kwargs):
... ...
@ret_cls(models.LightLevel) @ret_cls(models.LightLevel)
@ -468,12 +476,12 @@ class HughApi(SubRouter):
@ret_cls(models.LightLevel) @ret_cls(models.LightLevel)
@route("GET", "/resource/light_level/{light_level_id}") @route("GET", "/resource/light_level/{light_level_id}")
async def get_light_level(self, light_level_id: str): async def get_light_level(self, light_level_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/light_level/{light_level_id}") @route("PUT", "/resource/light_level/{light_level_id}")
async def set_light_level(self, light_level_id: str, **kwargs): async def set_light_level(self, light_level_id: UUID, **kwargs):
... ...
@ret_cls(models.Button) @ret_cls(models.Button)
@ -483,12 +491,12 @@ class HughApi(SubRouter):
@ret_cls(models.Button) @ret_cls(models.Button)
@route("GET", "/resource/button/{button_id}") @route("GET", "/resource/button/{button_id}")
async def get_button(self, button_id: str): async def get_button(self, button_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/button/{button_id}") @route("PUT", "/resource/button/{button_id}")
async def set_button(self, button_id: str, **kwargs): async def set_button(self, button_id: UUID, **kwargs):
... ...
@ret_cls(models.BehaviorScript) @ret_cls(models.BehaviorScript)
@ -498,7 +506,7 @@ class HughApi(SubRouter):
@ret_cls(models.BehaviorScript) @ret_cls(models.BehaviorScript)
@route("GET", "/resource/behavior_script/{behavior_script_id}") @route("GET", "/resource/behavior_script/{behavior_script_id}")
async def get_behavior_script(self, behavior_script_id: str): async def get_behavior_script(self, behavior_script_id: UUID):
... ...
@ret_cls(models.BehaviorInstance) @ret_cls(models.BehaviorInstance)
@ -513,17 +521,17 @@ class HughApi(SubRouter):
@ret_cls(models.BehaviorInstance) @ret_cls(models.BehaviorInstance)
@route("GET", "/resource/behavior_instance/{behavior_instance_id}") @route("GET", "/resource/behavior_instance/{behavior_instance_id}")
async def get_behavior_instance(self, behavior_instance_id: str): async def get_behavior_instance(self, behavior_instance_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/behavior_instance/{behavior_instance_id}") @route("PUT", "/resource/behavior_instance/{behavior_instance_id}")
async def set_behavior_instance(self, behavior_instance_id: str, **kwargs): async def set_behavior_instance(self, behavior_instance_id: UUID, **kwargs):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("DELETE", "/resource/behavior_instance/{behavior_instance_id}") @route("DELETE", "/resource/behavior_instance/{behavior_instance_id}")
async def delete_behavior_instance(self, behavior_instance_id: str): async def delete_behavior_instance(self, behavior_instance_id: UUID):
... ...
@ret_cls(models.GeofenceClient) @ret_cls(models.GeofenceClient)
@ -538,17 +546,17 @@ class HughApi(SubRouter):
@ret_cls(models.GeofenceClient) @ret_cls(models.GeofenceClient)
@route("GET", "/resource/geofence_client/{geofence_client_id}") @route("GET", "/resource/geofence_client/{geofence_client_id}")
async def get_geofence_client(self, geofence_client_id: str): async def get_geofence_client(self, geofence_client_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/geofence_client/{geofence_client_id}") @route("PUT", "/resource/geofence_client/{geofence_client_id}")
async def set_geofence_client(self, geofence_client_id: str, **kwargs): async def set_geofence_client(self, geofence_client_id: UUID, **kwargs):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("DELETE", "/resource/geofence_client/{geofence_client_id}") @route("DELETE", "/resource/geofence_client/{geofence_client_id}")
async def delete_geofence_client(self, geofence_client_id: str): async def delete_geofence_client(self, geofence_client_id: UUID):
... ...
@ret_cls(models.Geolocation) @ret_cls(models.Geolocation)
@ -558,12 +566,12 @@ class HughApi(SubRouter):
@ret_cls(models.Geolocation) @ret_cls(models.Geolocation)
@route("GET", "/resource/geolocation/{geolocation_id}") @route("GET", "/resource/geolocation/{geolocation_id}")
async def get_geolocation(self, geolocation_id: str): async def get_geolocation(self, geolocation_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/geolocation/{geolocation_id}") @route("PUT", "/resource/geolocation/{geolocation_id}")
async def set_geolocation(self, geolocation_id: str, **kwargs): async def set_geolocation(self, geolocation_id: UUID, **kwargs):
... ...
@ret_cls(models.EntertainmentConfiguration) @ret_cls(models.EntertainmentConfiguration)
@ -581,7 +589,7 @@ class HughApi(SubRouter):
"GET", "/resource/entertainment_configuration/{entertainment_configuration_id}" "GET", "/resource/entertainment_configuration/{entertainment_configuration_id}"
) )
async def get_entertainment_configuration( async def get_entertainment_configuration(
self, entertainment_configuration_id: str self, entertainment_configuration_id: UUID
): ):
... ...
@ -590,7 +598,7 @@ class HughApi(SubRouter):
"PUT", "/resource/entertainment_configuration/{entertainment_configuration_id}" "PUT", "/resource/entertainment_configuration/{entertainment_configuration_id}"
) )
async def set_entertainment_configuration( async def set_entertainment_configuration(
self, entertainment_configuration_id: str, **kwargs self, entertainment_configuration_id: UUID, **kwargs
): ):
... ...
@ -600,7 +608,7 @@ class HughApi(SubRouter):
"/resource/entertainment_configuration/{entertainment_configuration_id}", "/resource/entertainment_configuration/{entertainment_configuration_id}",
) )
async def delete_entertainment_configuration( async def delete_entertainment_configuration(
self, entertainment_configuration_id: str self, entertainment_configuration_id: UUID
): ):
... ...
@ -611,12 +619,12 @@ class HughApi(SubRouter):
@ret_cls(models.Entertainment) @ret_cls(models.Entertainment)
@route("GET", "/resource/entertainment/{entertainment_id}") @route("GET", "/resource/entertainment/{entertainment_id}")
async def get_entertainment(self, entertainment_id: str): async def get_entertainment(self, entertainment_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/entertainment/{entertainment_id}") @route("PUT", "/resource/entertainment/{entertainment_id}")
async def set_entertainment(self, entertainment_id: str, **kwargs): async def set_entertainment(self, entertainment_id: UUID, **kwargs):
... ...
@ret_cls(models.Homekit) @ret_cls(models.Homekit)
@ -626,12 +634,17 @@ class HughApi(SubRouter):
@ret_cls(models.Homekit) @ret_cls(models.Homekit)
@route("GET", "/resource/homekit/{homekit_id}") @route("GET", "/resource/homekit/{homekit_id}")
async def get_homekit(self, homekit_id: str): async def get_homekit(self, homekit_id: UUID):
... ...
@ret_cls(models._Identifier) @ret_cls(models._Identifier)
@route("PUT", "/resource/homekit/{homekit_id}") @route("PUT", "/resource/homekit/{homekit_id}")
async def set_homekit(self, homekit_id: str, **kwargs): async def set_homekit(
self,
homekit_id: UUID,
type: Optional[str] = None,
action: Optional[Literal["homekit_reset"]] = None,
):
... ...
@ret_cls(models.Resource) @ret_cls(models.Resource)

@ -1,4 +1,4 @@
from typing import Any, Literal, Optional, Generic, TypeVar from typing import Any, Literal, Optional, Generic, TypeAlias, TypeVar
from uuid import UUID from uuid import UUID
from dataclasses import dataclass from dataclasses import dataclass
from enum import Enum, auto from enum import Enum, auto
@ -7,6 +7,7 @@ from pydantic import BaseModel, Field
__all__ = ( __all__ = (
"Archetype", "Archetype",
"RoomType",
"Room", "Room",
"Light", "Light",
"Scene", "Scene",
@ -27,11 +28,64 @@ __all__ = (
"GeofenceClient", "GeofenceClient",
"Geolocation", "Geolocation",
"EntertainmentConfiguration", "EntertainmentConfiguration",
"Entertainment",
"Resource",
"Homekit",
) )
_T_M: TypeAlias = "Archetype | Room | Light | Scene | Zone | BridgeHome | GroupedLight | Device | Bridge | DevicePower | ZigbeeConnectivity | ZGPConnectivity | Motion | Temperature | LightLevel | Button | BehaviorScript | BehaviorInstance | GeofenceClient | Geolocation | EntertainmentConfiguration | Entertainment | Resource | Homekit"
_T = TypeVar("_T") _T = TypeVar("_T")
class RoomType(Enum):
@staticmethod
def _generate_next_value_(name, start, count, last_values):
return name.lower()
LIVING_ROOM = auto()
KITCHEN = auto()
DINING = auto()
BEDROOM = auto()
KIDS_BEDROOM = auto()
BATHROOM = auto()
NURSERY = auto()
RECREATION = auto()
OFFICE = auto()
GYM = auto()
HALLWAY = auto()
TOILET = auto()
FRONT_DOOR = auto()
GARAGE = auto()
TERRACE = auto()
GARDEN = auto()
DRIVEWAY = auto()
CARPORT = auto()
HOME = auto()
DOWNSTAIRS = auto()
UPSTAIRS = auto()
TOP_FLOOR = auto()
ATTIC = auto()
GUEST_ROOM = auto()
STAIRCASE = auto()
LOUNGE = auto()
MAN_CAVE = auto()
COMPUTER = auto()
STUDIO = auto()
MUSIC = auto()
TV = auto()
READING = auto()
CLOSET = auto()
STORAGE = auto()
LAUNDRY_ROOM = auto()
BALCONY = auto()
PORCH = auto()
BARBECUE = auto()
POOL = auto()
OTHER = auto()
class Archetype(Enum): class Archetype(Enum):
@staticmethod @staticmethod
def _generate_next_value_(name, start, count, last_values): def _generate_next_value_(name, start, count, last_values):
@ -109,7 +163,7 @@ class _Identifier:
@dataclass(frozen=True) @dataclass(frozen=True)
class _Metadata: class _Metadata:
name: str name: str
archetype: Optional[Archetype] = Archetype.UNKNOWN_ARCHETYPE archetype: Optional[Archetype | RoomType] = Archetype.UNKNOWN_ARCHETYPE
image: Optional[_Identifier] = Field(None, repr=False) image: Optional[_Identifier] = Field(None, repr=False)
@ -165,7 +219,9 @@ class _Lights(_HueGrouped):
class Light(Generic[_T], BaseModel): class Light(Generic[_T], BaseModel):
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field(
..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$"
)
owner: _Identifier owner: _Identifier
metadata: _Metadata metadata: _Metadata
on: _On = Field(repr=False) on: _On = Field(repr=False)
@ -217,7 +273,9 @@ class _Scenes(_HueGrouped):
class Scene(BaseModel): class Scene(BaseModel):
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field(
..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$"
)
metadata: _Metadata metadata: _Metadata
group: _Identifier group: _Identifier
actions: list["_Scenes.Actions"] actions: list["_Scenes.Actions"]
@ -233,7 +291,7 @@ _Scenes.update()
class Room(BaseModel): class Room(BaseModel):
type: Literal["room"] type: Literal["room"]
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
services: list[_Identifier] services: list[_Identifier]
metadata: _Metadata metadata: _Metadata
children: list[_Identifier] children: list[_Identifier]
@ -242,7 +300,7 @@ class Room(BaseModel):
class Zone(BaseModel): class Zone(BaseModel):
type: Literal["zone"] type: Literal["zone"]
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
services: list[_Identifier] services: list[_Identifier]
metadata: _Metadata metadata: _Metadata
children: list[_Identifier] children: list[_Identifier]
@ -251,7 +309,7 @@ class Zone(BaseModel):
class BridgeHome(BaseModel): class BridgeHome(BaseModel):
type: Literal["bridge_home"] type: Literal["bridge_home"]
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
services: list[_Identifier] services: list[_Identifier]
children: list[_Identifier] children: list[_Identifier]
@ -259,9 +317,9 @@ class BridgeHome(BaseModel):
class GroupedLight(BaseModel): class GroupedLight(BaseModel):
type: Literal["grouped_light"] type: Literal["grouped_light"]
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
on: _On = Field(repr=False) on: _On = Field(repr=False)
alert: list[str] alert: dict[str, list[str]]
class _ProductData(BaseModel): class _ProductData(BaseModel):
@ -277,7 +335,7 @@ class _ProductData(BaseModel):
class Device(BaseModel): class Device(BaseModel):
type: Literal["device"] type: Literal["device"]
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
services: list[_Identifier] services: list[_Identifier]
metadata: _Metadata metadata: _Metadata
product_data: _ProductData product_data: _ProductData
@ -286,20 +344,20 @@ class Device(BaseModel):
class Bridge(BaseModel): class Bridge(BaseModel):
type: Literal["bridge"] type: Literal["bridge"]
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
bridge_id: str bridge_id: str
time_zone: dict[str, str] time_zone: dict[str, str]
class _PowerState(BaseModel): class _PowerState(BaseModel):
battery_state: Literal["normal", "low", "critical"] battery_state: Literal["normal", "low", "critical"]
battery_level: float = Field(lt=100.0, gt=0.0) battery_level: float = Field(le=100.0, ge=0.0)
class DevicePower(BaseModel): class DevicePower(BaseModel):
type: Literal["device_power"] type: Literal["device_power"]
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
owner: _Identifier owner: _Identifier
power_state: _PowerState power_state: _PowerState
@ -307,7 +365,7 @@ class DevicePower(BaseModel):
class ZigbeeConnectivity(BaseModel): class ZigbeeConnectivity(BaseModel):
type: Literal["zigbee_connectivity"] type: Literal["zigbee_connectivity"]
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
owner: _Identifier owner: _Identifier
status: Literal[ status: Literal[
"connected", "disconnected", "connectivity_issue", "unidirectional_incoming" "connected", "disconnected", "connectivity_issue", "unidirectional_incoming"
@ -318,7 +376,7 @@ class ZigbeeConnectivity(BaseModel):
class ZGPConnectivity(BaseModel): class ZGPConnectivity(BaseModel):
type: Literal["zgp_connectivity"] type: Literal["zgp_connectivity"]
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
owner: _Identifier owner: _Identifier
status: Literal[ status: Literal[
"connected", "disconnected", "connectivity_issue", "unidirectional_incoming" "connected", "disconnected", "connectivity_issue", "unidirectional_incoming"
@ -329,7 +387,7 @@ class ZGPConnectivity(BaseModel):
class Motion(BaseModel): class Motion(BaseModel):
type: Literal["motion"] type: Literal["motion"]
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
owner: _Identifier owner: _Identifier
enabled: bool enabled: bool
motion: dict[str, bool] motion: dict[str, bool]
@ -343,7 +401,7 @@ class _Temp(BaseModel):
class Temperature(BaseModel): class Temperature(BaseModel):
type: Literal["temperature"] type: Literal["temperature"]
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
owner: _Identifier owner: _Identifier
enabled: bool enabled: bool
temperature: _Temp temperature: _Temp
@ -357,7 +415,7 @@ class _Light(BaseModel):
class LightLevel(BaseModel): class LightLevel(BaseModel):
type: Literal["light_level"] type: Literal["light_level"]
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
owner: _Identifier owner: _Identifier
enabled: bool enabled: bool
light: _Light light: _Light
@ -366,7 +424,7 @@ class LightLevel(BaseModel):
class Button(BaseModel): class Button(BaseModel):
type: Literal["button"] type: Literal["button"]
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
owner: _Identifier owner: _Identifier
metadata: dict[Literal["control_id"], int] metadata: dict[Literal["control_id"], int]
button: dict[ button: dict[
@ -384,7 +442,7 @@ class Button(BaseModel):
class BehaviorScript(BaseModel): class BehaviorScript(BaseModel):
type: Literal["behavior_script"] type: Literal["behavior_script"]
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
description: str description: str
configuration_schema: dict[str, Any] configuration_schema: dict[str, Any]
trigger_schema: dict[str, Any] trigger_schema: dict[str, Any]
@ -402,7 +460,7 @@ class _Dependee(BaseModel):
class BehaviorInstance(BaseModel): class BehaviorInstance(BaseModel):
type: Literal["behavior_instance"] type: Literal["behavior_instance"]
id: UUID id: UUID
id_v1: str = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
script_id: str script_id: str
enabled: bool enabled: bool
state: Optional[dict[str, Any]] state: Optional[dict[str, Any]]
@ -417,14 +475,14 @@ class BehaviorInstance(BaseModel):
class GeofenceClient(BaseModel): class GeofenceClient(BaseModel):
type: Literal["geofence_client"] type: Literal["geofence_client"]
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
name: str name: str
class Geolocation(BaseModel): class Geolocation(BaseModel):
type: Literal["geolocation"] type: Literal["geolocation"]
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
is_configured: bool = False is_configured: bool = False
@ -433,29 +491,81 @@ class _StreamProxy(BaseModel):
node: _Identifier node: _Identifier
class _XYZ(BaseModel):
x: float = Field(ge=-1.0, le=1.0)
y: float = Field(ge=-1.0, le=1.0)
z: float = Field(ge=-1.0, le=1.0)
class _SegmentRef(BaseModel):
service: _Identifier
index: int
class _EntertainmentChannel(BaseModel):
channel_id: int = Field(ge=0, le=255)
position: _XYZ
members: list[_SegmentRef]
class _ServiceLocation(BaseModel):
service: _Identifier
position: _XYZ
positions: list[_XYZ] = Field(max_items=2, min_items=1)
class _EntertainmentLocation(BaseModel):
service_location: Optional[list[_ServiceLocation]] = []
class EntertainmentConfiguration(BaseModel): class EntertainmentConfiguration(BaseModel):
type: Literal["entertainment_configuration"] type: Literal["entertainment_configuration"]
id: UUID id: UUID
id_v1: str = Field(..., regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$") id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
metadata: dict[Literal["name"], str] metadata: dict[Literal["name"], str]
name: Optional[str] = "" name: Optional[str] = ""
configuration_type: Literal["screen", "monitor", "music", "3dspace", "other"] configuration_type: Literal["screen", "monitor", "music", "3dspace", "other"]
status: Literal["active", "inactive"] status: Literal["active", "inactive"]
active_streamer: _Identifier active_streamer: Optional[_Identifier] = None
stream_proxy: _StreamProxy stream_proxy: _StreamProxy
... # TODO: finish the last 4 objects channels: list[_EntertainmentChannel]
locations: Optional[_EntertainmentLocation] = None
light_services: list[_Identifier]
class _Segment(BaseModel):
start: int = Field(..., ge=0)
length: int = Field(..., ge=1)
class _SegmentManager(BaseModel):
configurable: bool
max_segments: int = Field(..., ge=1)
segments: list[_Segment]
class Entertainment(BaseModel): class Entertainment(BaseModel):
... type: Literal["entertainment"]
id: UUID
id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
owner: _Identifier
renderer: bool
proxy: bool
max_streams: Optional[int] = Field(1, ge=1)
segments: Optional[_SegmentManager] = None
class Homekit(BaseModel): class Homekit(BaseModel):
... id: UUID
type: Optional[str]
id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
status: Literal["paired", "pairing", "unpaired"]
class Resource(BaseModel): class Resource(BaseModel):
... id: UUID
type: Optional[str]
id_v1: Optional[str] = Field("", regex=r"^(\/[a-z]{4,32}\/[0-9a-zA-Z-]{1,32})?$")
Light = _Lights.Light Light = _Lights.Light

37
test.py

@ -9,20 +9,31 @@ except ImportError:
async def main(): async def main():
router = Router("user api key") router = Router("your api key")
lights = await router.get_lights() print(await router.get_lights())
for light in lights: print(await router.get_scenes())
detailed_light = await router.get_light(light_id=str(light.id)) # noqa print(await router.get_devices())
print(light, detailed_light) print(await router.get_rooms())
print(await router.get_zones())
scenes = await router.get_scenes() print(await router.get_bridge_homes())
for scene in scenes: print(await router.get_grouped_lights())
print(scene) print(await router.get_bridges())
print(await router.get_device_powers())
devices = await router.get_devices() print(await router.get_zigbee_connectivities())
for device in devices: print(await router.get_zgb_connectivities())
print(device) print(await router.get_motions())
print(await router.get_temperatures())
print(await router.get_light_levels())
print(await router.get_buttons())
print(await router.get_behavior_scripts())
print(await router.get_behavior_instances())
print(await router.get_geofence_clients())
print(await router.get_geolocations())
print(await router.get_entertainment_configurations())
print(await router.get_entertainments())
print(await router.get_homekits())
print(await router.get_resources())
run(main()) run(main())