diff --git a/apps/apps.yaml b/apps/apps.yaml index 07fe884..d036ae7 100644 --- a/apps/apps.yaml +++ b/apps/apps.yaml @@ -4,12 +4,12 @@ hello_world: living_room_tv: module: tv - class: LivingRoomTV + class: SoundBar + device: BoseTV remote_entity: remote.broadlink_remote playing_entity: media_player.sony_google_cast - # media_entity: media_player.living_room_tv - # hardware_entity: media_player.sony_kd_65x85k - + off_entity: media_player.sony_bravia + scene_detect: module: scene_detect class: MotionCanceller diff --git a/apps/tv.py b/apps/tv.py index 39ddddd..173843c 100644 --- a/apps/tv.py +++ b/apps/tv.py @@ -6,59 +6,58 @@ from appdaemon.plugins.hass.hassapi import Hass @dataclass(init=False) -class LivingRoomTV(Hass): - remote_entity: str = None - playing_entity: str = None - # media_entity: str = None - # hardware_entity: str = None +class SoundBar(Hass): + """Turns on the soundbar by sending a command with the Broadlink remote. + - Turns on when the playing_entity goes to playing + - Turns off when the off_entity turns off + + """ + device: str + remote_entity: Entity + playing_entity: Entity + off_entity: Entity def initialize(self): - self.log(self.args) + self.set_fields() + + self.listen_state(self.turn_on_soundbar, self.playing_entity.entity_id, new='playing') + self.log(f'Waiting for {self.playing_entity} to go to playing') + + self.listen_state(self.hardware_off_callback, self.off_entity.entity_id, new='off') + self.log(f'Waiting for {self.off_entity} to go to off') + + def set_fields(self): for f in fields(self): if f.name in self.args: - entity_id = self.args[f.name] - if not self.entity_exists(entity_id): - self.log(f'{entity_id} does not exist', level="WARNING") + arg = self.args[f.name] + if f.type == Entity: + if not self.entity_exists(arg): + self.log(f'{arg} does not exist', level="WARNING") + else: + setattr(self, f.name, self.get_entity(arg)) else: - setattr(self, f.name, entity_id) + setattr(self, f.name, arg) else: self.log(f'{f.name} field is unset', level="WARNING") self.log(repr(self)) - self.listen_state(self.turn_on_soundbar, self.playing_entity, new='playing') - self.log(f'Waiting for {self.playing_entity} to go to playing') + def send_remote_command(self, command: str): + if self.remote_entity.state != 'on': + self.log('Turning on remote') + self.remote_entity.turn_on() + + self.log(f'Sending remote command: {command}') + self.call_service( + service='remote/send_command', + entity_id=self.remote_entity.entity_id, + device='BoseTV', + command=command + ) def turn_on_soundbar(self, entity=None, attribute=None, old=None, new=None, kwargs=None): - if self.get_state(self.remote_entity) != 'on': - self.log('Turning on remote') - self.turn_on(self.remote_entity) - # if self.remote_entity.state != 'on': - # self.log('Turning on remote') - # self.remote_entity.turn_on() - - self.log('Turning on soundbar') - self.call_service(service='remote/send_command', - entity_id=self.remote_entity, - device='BoseTV', command='TV') - - def state_change(self, entity=None, attribute=None, old=None, new=None, kwargs=None): - try: - if entity.endswith('2') or entity.endswith('3'): - name = new['attributes']['entity_id'] - app_name = new['attributes']['app_name'] - state = new['state'] - self.log(f'{name}: {app_name} {state}') - else: - self.log(f'{entity}: {new}') - except KeyError as e: - self.log(f'Failed getting attribute {e} from {entity}') - - def cancel_callbacks(self, entity=None, attribute=None, old=None, new=None, kwargs=None): - if (callbacks := self.get_scheduler_entries().get(self.name)): - for handle, info in callbacks.items(): - self.cancel_timer(handle) - self.log(f'Cancelled {handle}') + self.log(f'{self.playing_entity} is playing') + self.send_remote_command(command='TV') def hardware_off_callback(self, entity=None, attribute=None, old=None, new=None, kwargs=None): - self.log('Hardware turned off') - self.media_entity.turn_off() + self.log(f'{self.off_entity} is off') + self.send_remote_command(command='power')