From 8b7294b4451846d52f1e48c0b298a9e22f159c96 Mon Sep 17 00:00:00 2001 From: John Lancaster <32917998+jsl12@users.noreply.github.com> Date: Sun, 1 Sep 2024 21:07:29 -0500 Subject: [PATCH] broke out virtual button --- src/room_control/button.py | 83 ++++++++++++++++++-------------- src/room_control/room_control.py | 4 +- 2 files changed, 49 insertions(+), 38 deletions(-) diff --git a/src/room_control/button.py b/src/room_control/button.py index f17c98b..67f2874 100644 --- a/src/room_control/button.py +++ b/src/room_control/button.py @@ -1,6 +1,5 @@ import json from dataclasses import dataclass -from datetime import datetime from typing import TYPE_CHECKING, Any, Dict from appdaemon.entity import Entity @@ -26,48 +25,13 @@ class Button: namespace='mqtt', button=self.button_name, ) - self.create_button_entity() self.logger.info(f'MQTT topic [topic]{topic}[/] controls [room]{self.adapi.name}[/]') - @property - def eid(self) -> str: - return f'input_button.{self.adapi.name}' - - @property - def virtual_entity(self) -> Entity: - if not self.adapi.entity_exists(self.eid): - self.adapi.set_state(self.eid, state=datetime.now()) - - return self.adapi.get_entity(self.eid) - - def create_button_entity(self): - self.adapi.listen_event( - self.handle_virtual_button, domain='input_button', service='press', entity_id=self.eid - ) - self.logger.info(f'Listening for button press service call on [purple]{self.eid}[/]') - - def handle_virtual_button( - self, event_name: str, data: Dict[str, Any], **kwargs: Dict[str, Any] - ): - if event_name == 'appd_started': - return - elif event_name == 'state_changed': - return - - try: - if data['service_data']['entity_id'] == self.eid: - self.logger.info(f'Virtual button press: {event_name}') - # self.virtual_entity.set_state(state=datetime.now()) - self.virtual_entity.set_state(state=self.adapi.get_now()) - self.do_action('single') - except KeyError as e: - self.logger.error(f'Bad data from {event_name}: {json.dumps(data, indent=4)}') - def handle_button(self, event_name: str, data: Dict[str, Any], **kwargs: Dict[str, Any]): if event_name == 'appd_started': return - self.logger.info(f'Button callback: {event_name}, {data}') + # self.logger.info(f'Button callback: {event_name}, {data}') try: payload = json.loads(data['payload']) action = payload['action'] @@ -84,3 +48,48 @@ class Button: self.adapi.call_service( f'{self.adapi.name}/toggle', namespace='controller', cause='button' ) + + +@dataclass +class VirtualButton(Button): + def __post_init__(self): + self.logger = console.load_rich_config(self.adapi.name, 'Button') + + friendly_name = self.adapi.name.title().replace('_', ' ') + ' Button' + + kwargs = {'entity_id': self.eid, 'friendly_name': friendly_name} + + if not self.adapi.entity_exists(self.eid): + self.adapi.set_state(state=self.adapi.get_now(), **kwargs) + self.logger.info(f'Created entity [green]{self.eid}[/]') + else: + self.adapi.set_state(**kwargs) + self.logger.info(f'Set friendly name [green]{self.virtual_entity.friendly_name}[/]') + + self.adapi.listen_event(self.handle_virtual_button, entity_id=self.eid) + + @property + def eid(self) -> str: + return f'input_button.{self.adapi.name}' + + @property + def virtual_entity(self) -> Entity: + return self.adapi.get_entity(self.eid) + + def handle_virtual_button( + self, event_name: str, data: Dict[str, Any], **kwargs: Dict[str, Any] + ): + if ( + event_name == 'call_service' + and data.get('service') == 'press' + and (sd := data.get('service_data')) + and sd.get('entity_id') == self.eid + ): + try: + if data['service_data']['entity_id'] == self.eid: + self.logger.info(f'Virtual button press: {event_name}') + # self.virtual_entity.set_state(state=datetime.now()) + self.virtual_entity.set_state(state=self.adapi.get_now()) + self.do_action('single') + except KeyError as e: + self.logger.error(f'Bad data from {event_name}: {json.dumps(data, indent=4)}') diff --git a/src/room_control/room_control.py b/src/room_control/room_control.py index a8974d3..a1bb159 100755 --- a/src/room_control/room_control.py +++ b/src/room_control/room_control.py @@ -10,7 +10,7 @@ from appdaemon.plugins.hass.hassapi import Hass from astral.location import Location from . import console -from .button import Button +from .button import Button, VirtualButton from .door import Door from .model import ControllerStateConfig, RoomControllerConfig from .motion import MotionSensor @@ -82,9 +82,11 @@ class RoomController(Hass): if button := self.args.get('button'): if isinstance(button, str): Button(self, button_name=button) + VirtualButton(self, button_name=button) elif isinstance(button, list) and all(isinstance(b, str) for b in button): for b in button: Button(self, button_name=b) + VirtualButton(self, button_name=button) if door := self.args.get('door'): if isinstance(door, str):