broke out virtual button
This commit is contained in:
@@ -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)}')
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
Reference in New Issue
Block a user