Skip to content

Commit

Permalink
Introduce IKEA -> 'event buss' message broker
Browse files Browse the repository at this point in the history
  • Loading branch information
Toomaz Toplak committed Feb 25, 2024
1 parent 8dabf7e commit a88b62c
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 10 deletions.
29 changes: 19 additions & 10 deletions custom_components/dirigera_platform/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
from .const import DOMAIN

import logging
from .message_broker import DirigeraMessageBroker

logger = logging.getLogger("custom_components.dirigera_platform")

# Validation of the user's configuration
Expand All @@ -40,14 +42,14 @@ def handle_dump_data(call):
if ip == "mock":
logger.info("{ MOCK JSON }")
else:
hub = dirigera.Hub(token, ip)
hub = dirigera.Hub(token, ip)
json_resp = hub.get("/devices")
logger.info(json_resp)
logger.info("--------------")

logger.info("=== END Devices JSON ===")
hass.services.async_register(DOMAIN, "dump_data", handle_dump_data)

hass.services.async_register(DOMAIN, "dump_data", handle_dump_data)
return True

async def async_setup_entry(hass: core.HomeAssistant, entry: config_entries.ConfigEntry) -> bool:
Expand All @@ -60,23 +62,29 @@ async def async_setup_entry(hass: core.HomeAssistant, entry: config_entries.Conf

logger.debug("hass_data")
logger.debug(hass_data)

ip = hass_data[CONF_IP_ADDRESS]

token = hass_data[CONF_TOKEN]
# Create a broker that runs in a separate thread
# It listens to events from the hub and dispatches them to the event bus
DirigeraMessageBroker(ip, token, hass)

# Registers update listener to update config entry when options are updated.
unsub_options_update_listener = entry.add_update_listener(options_update_listener)

# Store a reference to the unsubscribe function to cleanup if an entry is unloaded.
hass_data["unsub_options_update_listener"] = unsub_options_update_listener
hass.data[DOMAIN][entry.entry_id] = hass_data

# Setup the entities

hass.async_create_task(hass.config_entries.async_forward_entry_setup(entry, "light"))
hass.async_create_task(hass.config_entries.async_forward_entry_setup(entry, "event"))
hass.async_create_task(hass.config_entries.async_forward_entry_setup(entry, "switch"))
hass.async_create_task(hass.config_entries.async_forward_entry_setup(entry, "binary_sensor"))
hass.async_create_task(hass.config_entries.async_forward_entry_setup(entry, "sensor"))
hass.async_create_task(hass.config_entries.async_forward_entry_setup(entry, "cover"))

logger.debug("Complete async_setup_entry...")

return True
Expand Down Expand Up @@ -108,4 +116,5 @@ async def async_remove_config_entry_device( hass: HomeAssistant, config_entry: c
logger.info("Got request to remove device")
logger.info(config_entry)
logger.info(device_entry)
return True

return True
89 changes: 89 additions & 0 deletions custom_components/dirigera_platform/mesage_broker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import threading
import logging
from typing import Any

import json
import time

from homeassistant import core

import dirigera
from .dirigera_lib_patch import HubX

logger = logging.getLogger("custom_components.dirigera_platform")


class DirigeraMessageBroker:
def __init__(self, ip, token, hass: core.HomeAssistant) -> None:
self._hub = HubX(token, ip)
self._hass = hass
self._websocket_thread = threading.Thread(target=self.run_websocket_app)
self._websocket_thread.start()

def handle_event(self, ws: Any, message: str) -> None:
# Parse the incoming message
message_dict = json.loads(message)
data = message_dict.get("data", {})

handled = False
handled = self.handle_button_event(data)
if not handled:
handled = self.handle_light_event(data)

def handle_ws_error(self, ws: Any, message: str) -> None:
logger.error(message)

def handle_ws_close(self, ws: Any, status_code: Any, close_msg: str) -> None:
logger.debug("WS closed...")
logger.debug("Status code: %s, Close message: %s", status_code, close_msg)
self.run_websocket_app()

def run_websocket_app(self) -> None:
self._hub.create_event_listener(
on_message=self.handle_event,
on_error=self.handle_ws_error,
on_close=self.handle_ws_close,
)

def handle_button_event(self, data) -> None:
# Check if triggers are present in the data
triggers = data.get("triggers", [])

# Filter triggers for 'controller' type
matching_triggers = [
trigger for trigger in triggers if trigger["type"] == "controller"
]

for trigger in matching_triggers:
pattern = trigger["trigger"]["clickPattern"]
if data["info"]["name"].startswith("ActionPress"):
eventName = "dirigera_message_button"

self._hass.bus.fire(
eventName,
{
"sourceDeviceId": trigger["trigger"]["deviceId"],
"pattern": pattern,
},
)

logger.debug(
"Button event detected... %s", pattern
)
return True
return False

def handle_light_event(self, data) -> None:
logger.debug("handle_light_event...")
if "type" in data and data["type"] == "light":
eventName = "dirigera_message_light"
self._hass.bus.fire(
eventName,
{
"sourceDeviceId": data["id"],
"attributes": data["attributes"],
},
)
logger.debug("Light event detected... ")
return True
return False

0 comments on commit a88b62c

Please sign in to comment.