Skip to content

Commit

Permalink
Use caching versions of Number and Switch
Browse files Browse the repository at this point in the history
  • Loading branch information
pzbitskiy committed Aug 7, 2024
1 parent bed9da6 commit 7ab3e4b
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 14 deletions.
4 changes: 4 additions & 0 deletions src/media_center_kb/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,10 @@ def devices(
result[name] = device
return result

def shutdown(self):
"""Power off the controller"""
self._board_control.shutdown()

@no_type_check
def commands_map(self) -> Dict[str, Callable]:
"""Returns dict of handlers by keycode"""
Expand Down
63 changes: 52 additions & 11 deletions src/media_center_kb/ha.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
"""HomeAssistant MQTT stuff"""

from abc import abstractmethod
import asyncio
import logging
from typing import Any, Callable, Dict, Iterable
from typing import Any, Dict, Iterable, Optional
import uuid

from ha_mqtt_discoverable import Settings, DeviceInfo
Expand All @@ -27,15 +28,54 @@ def get_mac_address() -> str:
return mac_address


class ControllerIf:
"""Controller interface"""

@abstractmethod
def devices(self, _: Iterable[str]) -> Dict[str, PoweredDevice]:
"""Get devices by name"""

@abstractmethod
def shutdown(self):
"""Shutdown the controller"""


class CachedNumber(Number):
"""Number that remember its state"""

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._value: Optional[float] = None # type: ignore[annotation-unchecked]

def set_value(self, value: float):
if value != self._value:
self._value = value
super().set_value(value)


class CachedSwitch(Switch):
"""Switch that remembers its state"""

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._state: Optional[bool] = None # type: ignore[annotation-unchecked]

def update_state(self, state: bool):
if self._state != state:
self._state = state
super().update_state(state=state)


class SmartOutletHaDevice: # pylint: disable=too-many-instance-attributes
"""Smart outlet HA device with MQTT auto discovery"""

def __init__(
self,
device_provider: Callable[[Iterable[str]], Dict[str, PoweredDevice]],
controller: ControllerIf,
mqtt_settings: Dict[str, Any],
):
self._devices = device_provider(["tv", "turntable", "printer"])
self._controller = controller
self._devices = controller.devices(["tv", "turntable", "printer"])
self._mqtt_settings = Settings.MQTT(**mqtt_settings)

self._initialize_ha_devices()
Expand Down Expand Up @@ -83,7 +123,7 @@ def _initialize_ha_devices(self): # pylint: disable=too-many-locals
device=self._rpi_device_info,
)
rpi_switch_settings = Settings(mqtt=self._mqtt_settings, entity=rpi_switch_info)
self._rpi_switch = Switch(rpi_switch_settings, self.rpi_switch_mqtt)
self._rpi_switch = CachedSwitch(rpi_switch_settings, self.rpi_switch_mqtt)

tv_switch_info = SwitchInfo(
name="Power",
Expand All @@ -92,7 +132,7 @@ def _initialize_ha_devices(self): # pylint: disable=too-many-locals
device=self._tv_device_info,
)
tv_switch_settings = Settings(mqtt=self._mqtt_settings, entity=tv_switch_info)
self._tv_switch = Switch(tv_switch_settings, self.tv_switch_mqtt)
self._tv_switch = CachedSwitch(tv_switch_settings, self.tv_switch_mqtt)

turntable_switch_info = SwitchInfo(
name="Power",
Expand All @@ -103,7 +143,7 @@ def _initialize_ha_devices(self): # pylint: disable=too-many-locals
turntable_switch_settings = Settings(
mqtt=self._mqtt_settings, entity=turntable_switch_info
)
self._turntable_switch = Switch(
self._turntable_switch = CachedSwitch(
turntable_switch_settings, self.turnable_switch_mqtt
)

Expand All @@ -116,7 +156,9 @@ def _initialize_ha_devices(self): # pylint: disable=too-many-locals
printer_switch_settings = Settings(
mqtt=self._mqtt_settings, entity=printer_switch_info
)
self._printer_switch = Switch(printer_switch_settings, self.printer_switch_mqtt)
self._printer_switch = CachedSwitch(
printer_switch_settings, self.printer_switch_mqtt
)

# add volume
tv_volume_info = NumberInfo(
Expand All @@ -129,7 +171,7 @@ def _initialize_ha_devices(self): # pylint: disable=too-many-locals
device=self._tv_device_info,
)
tv_volume_settings = Settings(mqtt=self._mqtt_settings, entity=tv_volume_info)
self._tv_volume = Number(
self._tv_volume = CachedNumber(
tv_volume_settings, lambda c, u, m: self.tv_volume_mqtt(c, m)
)

Expand All @@ -145,7 +187,7 @@ def _initialize_ha_devices(self): # pylint: disable=too-many-locals
turntable_volume_settings = Settings(
mqtt=self._mqtt_settings, entity=turntable_volume_info
)
self._turntable_volume = Number(
self._turntable_volume = CachedNumber(
turntable_volume_settings, lambda c, u, m: self.turntable_volume_mqtt(c, m)
)

Expand All @@ -169,8 +211,7 @@ def rpi_switch_mqtt(
if payload == "OFF":
# Let HA know that the switch was successfully deactivated
self._rpi_switch.off()
# TBD
# self._handlers["shutdown"]()
self._controller.shutdown()
elif payload == "ON":
# cannot power on itself
pass
Expand Down
4 changes: 1 addition & 3 deletions src/media_center_kb/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,7 @@ async def main():
if not args.no_serial:
coros.append(ysp.get_async_coro(loop))
if mqtt_settings and not args.no_ha:
coros.append(
ha_loop(SmartOutletHaDevice(controller.devices, mqtt_settings))
)
coros.append(ha_loop(SmartOutletHaDevice(controller, mqtt_settings)))

await asyncio.gather(*coros)
except asyncio.CancelledError:
Expand Down

0 comments on commit 7ab3e4b

Please sign in to comment.