Skip to content

Commit

Permalink
Add event support (#26)
Browse files Browse the repository at this point in the history
* Add event support

* Fix details from code review
  • Loading branch information
rappenze authored Sep 25, 2023
1 parent 988a655 commit 5daa438
Show file tree
Hide file tree
Showing 9 changed files with 1,370 additions and 1 deletion.
41 changes: 41 additions & 0 deletions pyfibaro/fibaro_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,28 @@ def target_level(self) -> float:
"""Returns the target level or 0 if there is no value."""
return float(self.properties.get("targetLevel", 0.0))

@property
def has_central_scene_event(self) -> bool:
"""Returns true if the device can issue central scene events."""
return "centralSceneSupport" in self.properties

@property
def central_scene_event(self) -> list[SceneEvent]:
"""Returns list of potential scene events."""
central_scene_support = []
value = self.properties.get("centralSceneSupport")
if isinstance(value, list):
central_scene_support = value
if isinstance(value, str):
central_scene_support = json.loads(value)

result = []
for central_scene in central_scene_support:
key_id = int(central_scene.get("keyId"))
key_attributes = central_scene.get("keyAttributes")
result.append(SceneEvent(key_id, key_attributes))
return result

def execute_action(self, action: str, arguments: list[Any] | None = None) -> Any:
"""Execute a device action.
Expand Down Expand Up @@ -511,3 +533,22 @@ def rgbw_color(self) -> tuple[int, int, int, int]:
if len(rgbw) != 4:
raise TypeError(f"Color does not have 4 parts: {color}")
return rgbw


class SceneEvent:
"""Model to read out the scene events."""

def __init__(self, key_id: int, key_attributes: list[str]) -> None:
"""Constructor."""
self._key_id = key_id
self._key_attributes = key_attributes

@property
def key_id(self) -> int:
"""Returns the key id."""
return self._key_id

@property
def key_event_types(self) -> list[str]:
"""Returns the possible key event types."""
return self._key_attributes
89 changes: 89 additions & 0 deletions pyfibaro/fibaro_state_resolver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
"""State object resolver for fibaro home center."""

import logging
from typing import Any

_LOGGER = logging.getLogger(__name__)


class FibaroEvent:
"""A fibaro event returned by state handler."""

def __init__(self, data: dict) -> None:
"""Constructor to init the object with the raw data."""
self.raw_data = data

@property
def event_type(self) -> str:
"""Returns the event type as string.
Most known event is "CentralSceneEvent" which is used for button press events.
"""
return self.raw_data.get("type", "")

@property
def fibaro_id(self) -> int:
"""The device id which throws the event."""
data = self.event_data
# id is used by HC3, deviceId by HC2
return int(data.get("id", data.get("deviceId")))

@property
def event_data(self) -> dict:
"""Returns the event data in raw format."""
return self.raw_data.get("data", {})

@property
def key_id(self) -> int:
"""Returns the key id."""
return int(self.event_data.get("keyId", 0))

@property
def key_event_type(self) -> str:
"""Returns the key event attribute.
For example Pressed, Released, HeldDown, ...
"""
return self.event_data.get("keyAttribute", "")


class FibaroStateChange:
"""A fibaro state change returned by state handler."""

def __init__(self, data: dict) -> None:
"""Constructor to init the object with the raw data."""
self.raw_data = data

@property
def fibaro_id(self) -> int:
"""The device id which throws the event."""
return int(self.raw_data.get("id"))

@property
def property_changes(self) -> dict[str, Any]:
"""The changes in the device properties."""
result: dict[str, Any] = {}

for property_name, value in self.raw_data.items():
# Ignore some attributes which are not relevant or returned separately
if property_name in ("log", "logTemp", "id"):
continue
result[property_name] = value

return result


class FibaroStateResolver:
"""State resolver allows typed access to a state object retunred by fibaro home center."""

def __init__(self, data: dict) -> None:
"""Init the object with the raw event object."""
self.raw_data = data

def get_events(self) -> list[FibaroEvent]:
"""Extract events from the state handle object."""
return [FibaroEvent(data) for data in self.raw_data.get("events", [])]

def get_state_updates(self) -> list[FibaroStateChange]:
"""Extract state changes from the state handle object."""
return [FibaroStateChange(data) for data in self.raw_data.get("changes", [])]
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = pyfibaro
version = 0.7.3
version = 0.7.4
description = Simple API to access fibaro home center from any Python 3 script. Designed for Home Assistant (but not only)
long_description = file: README.md
long_description_content_type = text/markdown
Expand Down
Loading

0 comments on commit 5daa438

Please sign in to comment.