from appdaemon.entity import Entity from appdaemon.plugins.hass.hassapi import Hass import json class TapDial(Hass): active_entity: Entity def initialize(self): self.tap_dial.listen_state(self.handle_state_change) self.log(f'0.0 Tap Dial entity: {self.tap_dial.entity_id}') @property def tap_dial(self) -> Entity: return self.get_entity(self.args['entity']) @property def step_size(self) -> int: return int(self.args.get('step_size', 25)) @property def init_brightness(self) -> int: return int(self.args.get('init_brightness', 200)) @property def max_brightness(self) -> int: return int(self.args.get('max_brightness', 254)) @property def active_entity_is_on(self) -> bool: return self.active_entity.get_state() == 'on' # Experiment to read and write various properties to a light.... @property def light_brightness(self) -> int: return self.active_entity.attributes['brightness'] @light_brightness.setter def light_brightness(self, val: int): return self.active_entity.turn_on(brightness=val) @property def light_color(self) -> list[int]: return self.active_entity.get_state('rgb_color') @light_color.setter def light_color(self, val: list[int]): return self.active_entity.turn_on(rgb_color=val) @property def light_effect(self) -> str: return self.active_entity.get_state('effect') @light_effect.setter def light_effect(self, val: str): return self.active_entity.turn_on(effect=val) def handle_state_change(self, entity: str, attribute: str, old: str, new: str, **kwargs): self.log(f'0.1 {new}') # Dial actions if new.startswith('dial_rotate') and self.active_entity_is_on: self.log('Ignore dial_rotate commands for now...') # Button actions elif new.endswith('release'): _, n, typ, _ = new.split('_', 4) # type will be either press or hold self.log(f'2.1 Button {n} {typ}') if eid := self.args.get(f'button{n}'): self.active_entity = self.get_entity(eid) self.log(f'2.1.1 Set active entity to: {self.active_entity.name}') domain, entity = eid.split('.') match domain: case 'light': # Set the light to maximum brightness if the button is held. if typ == 'hold': self.log('Ignore button_hold command for now...') else: if self.active_entity_is_on: self.log(f'Current values for Brightness: {self.light_brightness}, RGB Color: {self.light_color}, Effect: {self.light_effect}') # self.log(f'New values for Color: {self.args.get(f"color{n}")} and Effect: {self.args.get(f"effect{n}")}') hex = self.args.get(f"color{n}") # self.log(f'Translate {self.args.get(f"color{n}")} to RGB {self.hex_to_rgb(hex)} ') br_val = self.args.get(f'brightness{n}') match n: case '1': # do nothing self.log(f'Made it to case{n}') # self.active_entity.turn_on(brightness=br_val,rgb_color=self.hex_to_rgb(hex),transition=10) self.active_entity.turn_on(brightness=br_val,rgb_color=self.hex_to_rgb(hex)) # self.active_entity.turn_on(rgb_color=self.hex_to_rgb('FFFFFF')) # self.active_entity.turn_on(effect='candle') # self.light_color = self.hex_to_rgb(hex) # self.light_effect = self.args.get(f'effect{n}') # self.log(json.dumps(self.active_entity.get_state('all'), indent=4)) case '2': # attempt to change brightness, color self.log(f'Made it to case{n}') # self.active_entity.turn_on(brightness=br_val,rgb_color=self.hex_to_rgb(hex),transition=10) self.active_entity.turn_on(brightness=br_val,rgb_color=self.hex_to_rgb(hex)) # self.active_entity.turn_on(rgb_color=self.hex_to_rgb('FFFFFF')) # self.active_entity.turn_on(effect='candle') # self.light_color = self.hex_to_rgb(hex) # self.light_effect = self.args.get(f'effect{n}') # self.log(json.dumps(self.active_entity.get_state('all'), indent=4)) case '3': # attempt to apply 'candle' effect self.log(f'Made it to case{n}') self.active_entity.turn_on(effect='stop_hue_effect') # self.active_entity.turn_on(effect='candle') self.active_entity.set_state(effect='fireplace') # self.log(json.dumps(self.active_entity.get_state('all'), indent=4)) case '4': # json.dump self.log(f'Made it to case{n}') # self.active_entity.turn_on(brightness=br_val,rgb_color=self.hex_to_rgb(hex),transition=10) # self.active_entity.turn_on(brightness=br_val,rgb_color=self.hex_to_rgb(hex)) # self.active_entity.turn_on(rgb_color=self.hex_to_rgb('FFFFFF')) # self.active_entity.turn_on(effect='candle') # self.light_color = self.hex_to_rgb(hex) # self.light_effect = self.args.get(f'effect{n}') self.log(json.dumps(self.active_entity.get_state('all'), indent=4)) else: self.log('The light is off...') case 'switch': self.log('Ignore non-light entities for now...') # This function was written by chatgpt... def hex_to_rgb(self, hex_color: str) -> list: # Remove the "#" if it's included hex_color = hex_color.lstrip('#') # Check if the string has a valid length if len(hex_color) != 6: raise ValueError(f"Invalid hex color: {hex_color}. Must be 6 characters long.") try: # Split the hex color into its RGB components and convert to integers r = int(hex_color[0:2], 16) g = int(hex_color[2:4], 16) b = int(hex_color[4:6], 16) return [r, g, b] except ValueError: raise ValueError(f"Invalid hex color: {hex_color}. Must contain only valid hex digits.")