broke out virtual button

This commit is contained in:
John Lancaster
2024-09-01 21:07:29 -05:00
parent e4dada011c
commit 8b7294b445
2 changed files with 49 additions and 38 deletions

View File

@@ -1,6 +1,5 @@
import json import json
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime
from typing import TYPE_CHECKING, Any, Dict from typing import TYPE_CHECKING, Any, Dict
from appdaemon.entity import Entity from appdaemon.entity import Entity
@@ -26,48 +25,13 @@ class Button:
namespace='mqtt', namespace='mqtt',
button=self.button_name, button=self.button_name,
) )
self.create_button_entity()
self.logger.info(f'MQTT topic [topic]{topic}[/] controls [room]{self.adapi.name}[/]') 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]): def handle_button(self, event_name: str, data: Dict[str, Any], **kwargs: Dict[str, Any]):
if event_name == 'appd_started': if event_name == 'appd_started':
return return
self.logger.info(f'Button callback: {event_name}, {data}') # self.logger.info(f'Button callback: {event_name}, {data}')
try: try:
payload = json.loads(data['payload']) payload = json.loads(data['payload'])
action = payload['action'] action = payload['action']
@@ -84,3 +48,48 @@ class Button:
self.adapi.call_service( self.adapi.call_service(
f'{self.adapi.name}/toggle', namespace='controller', cause='button' 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)}')

View File

@@ -10,7 +10,7 @@ from appdaemon.plugins.hass.hassapi import Hass
from astral.location import Location from astral.location import Location
from . import console from . import console
from .button import Button from .button import Button, VirtualButton
from .door import Door from .door import Door
from .model import ControllerStateConfig, RoomControllerConfig from .model import ControllerStateConfig, RoomControllerConfig
from .motion import MotionSensor from .motion import MotionSensor
@@ -82,9 +82,11 @@ class RoomController(Hass):
if button := self.args.get('button'): if button := self.args.get('button'):
if isinstance(button, str): if isinstance(button, str):
Button(self, button_name=button) Button(self, button_name=button)
VirtualButton(self, button_name=button)
elif isinstance(button, list) and all(isinstance(b, str) for b in button): elif isinstance(button, list) and all(isinstance(b, str) for b in button):
for b in button: for b in button:
Button(self, button_name=b) Button(self, button_name=b)
VirtualButton(self, button_name=button)
if door := self.args.get('door'): if door := self.args.get('door'):
if isinstance(door, str): if isinstance(door, str):