#!/usr/bin/python3 import inspect ############### # Action Tree # ############### """ 1: States 1: Lights 1: Kitchen Lights (Toggle) 1: Off 2: 10% 3: 55% 4: 100% 2: Main Room Lights (Toggle) [...] 3: Living Room Lights (Toggle) [...] 4: Bedroom Lights (Toggle) [...] 2: A/C 2: Main Room AC 1: Power 1: On 2: On 3: Off 4: Off 2: Mode 1: Cool 2: Heat 3: Fan 3: Fan Level 1: Auto 2: Quiet 3: Medium 4: High 4: Temperature 1: 72 2: 74 3: 76 4: 78 3: Living Room AC [...] 4: Bedroom AC [...] 3: Fans 1: Kitchen Fan 1: Off 2: 1 3: 2 4: 3 3: Living Room Fan [...] 4: Bedroom Fan [...] 2: Music 1: Join/unjoin speakers 1. Unjoin speakers # Select master 3. Living Room Sonos 4. Bedroom Sonos 2: Play Music 3: Play on Living Room Sonos 1: Spotify: Liked Songs 2: Spotify: Getting Things Done 4: Play on Bedroom Sonos 1: Spotify: Liked Songs 2: Spotify: Chill Sleep 3: Media Controls 3: Living Room Sonos 1. Pause 2. Play 3. Previous 4. Next 4: Bedroom Sonos [...] 4. Options: 3: Living Room Sonos 2: Crossfade 1: Off 2: On 3: Shuffle 1: Off 2: On 4: Repeat 1: Off 2: On 4: Bedroom Sonos [...] """ tree = { 1: { # State 1: { # Lights 1: { # Kitchen "function": lambda hass: hass.call_service("light/toggle",entity_id="light.kitchen_lights"), "description": "Kitchen Lights: Toggle", 1: { "function": lambda hass: set_brightness(hass,"light.kitchen_lights",0), "description": "Kitchen Lights: 0%" }, 2: { "function": lambda hass: set_brightness(hass,"light.kitchen_lights",10), "description": "Kitchen Lights: 10%" }, 3: { "function": lambda hass: set_brightness(hass,"light.kitchen_lights",55), "description": "Kitchen Lights: 55%" }, 4: { "function": lambda hass: set_brightness(hass,"light.kitchen_lights",100), "description": "Kitchen Lights: 100%" } }, 2: { # Main Room "function": lambda hass: hass.call_service("light/toggle",entity_id="light.mainroom_lights"), "description": "Main Room Lights: Toggle", 1: { "function": lambda hass: set_brightness(hass,"light.mainroom_lights",0), "description": "Main Room Lights: 0%" }, 2: { "function": lambda hass: set_brightness(hass,"light.mainroom_lights",10), "description": "Main Room Lights: 10%" }, 3: { "function": lambda hass: set_brightness(hass,"light.mainroom_lights",55), "description": "Main Room Lights: 55%" }, 4: { "function": lambda hass: set_brightness(hass,"light.mainroom_lights",100), "description": "Main Room Lights: 100%" } }, 3: { # Living Room "function": lambda hass: hass.call_service("light/toggle",entity_id="light.livingroom_lights"), "description": "Living Room Lights: Toggle", 1: { "function": lambda hass: set_brightness(hass,"light.livingroom_lights",0), "description": "Living Room Lights: 0%" }, 2: { "function": lambda hass: set_brightness(hass,"light.livingroom_lights",10), "description": "Living Room Lights: 10%" }, 3: { "function": lambda hass: set_brightness(hass,"light.livingroom_lights",55), "description": "Living Room Lights: 55%" }, 4: { "function": lambda hass: set_brightness(hass,"light.livingroom_lights",100), "description": "Living Room Lights: 100%" } }, 4: { # Bedroom "function": lambda hass: hass.call_service("light/toggle",entity_id="light.bedroom_lights"), "description": "Bedroom Lights: Toggle", 1: { "function": lambda hass: set_brightness(hass,"light.bedroom_lights",0), "description": "Bedroom Lights: 0%" }, 2: { "function": lambda hass: set_brightness(hass,"light.bedroom_lights",10), "description": "Bedroom Lights: 10%" }, 3: { "function": lambda hass: set_brightness(hass,"light.bedroom_lights",55), "description": "Bedroom Lights: 55%" }, 4: { "function": lambda hass: set_brightness(hass,"light.bedroom_lights",100), "description": "Bedroom Lights: 100%" } } }, 2: { # A/C 2: { # Main Room 1: { # Power 1: { "function": lambda hass: hass.turn_on("climate.mainroom_ac"), "description": "Main Room A/C Power: On" }, 2: { "function": lambda hass: hass.turn_on("climate.mainroom_ac"), "description": "Main Room A/C Power: On" }, 3: { "function": lambda hass: hass.turn_off("climate.mainroom_ac"), "description": "Main Room A/C Power: Off" }, 4: { "function": lambda hass: hass.turn_off("climate.mainroom_ac"), "description": "Main Room A/C Power: Off" }, }, 2: { # Mode 1: { "function": lambda hass: gree_set_mode(hass,"mainroom_ac","cool"), "description": "Main Room A/C Mode: Cool" }, 2: { "function": lambda hass: gree_set_mode(hass,"mainroom_ac","heat"), "description": "Main Room A/C Mode: Heat" }, 3: { "function": lambda hass: gree_set_mode(hass,"mainroom_ac","fan_only"), "description": "Main Room A/C Mode: Fan" } }, 3: { # Fan Level 1: { "function": lambda hass: gree_set_fan_level(hass,"mainroom_ac","auto"), "description": "Main Room A/C Fan Level: Auto" }, 2: { "function": lambda hass: gree_set_fan_level(hass,"mainroom_ac","quiet"), "description": "Main Room A/C Fan Level: Quiet" }, 3: { "function": lambda hass: gree_set_fan_level(hass,"mainroom_ac","medium"), "description": "Main Room A/C Fan Level: Medium" }, 4: { "function": lambda hass: gree_set_fan_level(hass,"mainroom_ac","high"), "description": "Main Room A/C Fan Level: High" } }, 4: { # Temperature 1: { "function": lambda hass: set_temperature(hass,"mainroom_ac",72), "description": "Main Room A/C Temperature: 72" }, 2: { "function": lambda hass: set_temperature(hass,"mainroom_ac",74), "description": "Main Room A/C Temperature: 74" }, 3: { "function": lambda hass: set_temperature(hass,"mainroom_ac",76), "description": "Main Room A/C Temperature: 76" }, 4: { "function": lambda hass: set_temperature(hass,"mainroom_ac",78), "description": "Main Room A/C Temperature: 78" } } }, 3: { # Living Room 1: { # Power 1: { "function": lambda hass: hass.turn_on("climate.livingroom_ac"), "description": "Living Room A/C Power: On" }, 2: { "function": lambda hass: hass.turn_on("climate.livingroom_ac"), "description": "Living Room A/C Power: On" }, 3: { "function": lambda hass: hass.turn_off("climate.livingroom_ac"), "description": "Living Room A/C Power: Off" }, 4: { "function": lambda hass: hass.turn_off("climate.livingroom_ac"), "description": "Living Room A/C Power: Off" }, }, 2: { # Mode 1: { "function": lambda hass: gree_set_mode(hass,"livingroom_ac","cool"), "description": "Living Room A/C Mode: Cool" }, 2: { "function": lambda hass: gree_set_mode(hass,"livingroom_ac","heat"), "description": "Living Room A/C Mode: Heat" }, 3: { "function": lambda hass: gree_set_mode(hass,"livingroom_ac","fan_only"), "description": "Living Room A/C Mode: Fan" } }, 3: { # Fan Level 1: { "function": lambda hass: gree_set_fan_level(hass,"livingroom_ac","auto"), "description": "Living Room A/C Fan Level: Auto" }, 2: { "function": lambda hass: gree_set_fan_level(hass,"livingroom_ac","quiet"), "description": "Living Room A/C Fan Level: Quiet" }, 3: { "function": lambda hass: gree_set_fan_level(hass,"livingroom_ac","medium"), "description": "Living Room A/C Fan Level: Medium" }, 4: { "function": lambda hass: gree_set_fan_level(hass,"livingroom_ac","high"), "description": "Living Room A/C Fan Level: High" } }, 4: { # Temperature 1: { "function": lambda hass: set_temperature(hass,"livingroom_ac",72), "description": "Living Room A/C Temperature: 72" }, 2: { "function": lambda hass: set_temperature(hass,"livingroom_ac",74), "description": "Living Room A/C Temperature: 74" }, 3: { "function": lambda hass: set_temperature(hass,"livingroom_ac",76), "description": "Living Room A/C Temperature: 76" }, 4: { "function": lambda hass: set_temperature(hass,"livingroom_ac",78), "description": "Living Room A/C Temperature: 78" } } }, 4: { # Bedroom 1: { # Power 1: { "function": lambda hass: hass.turn_on("climate.bedroom_ac"), "description": "Bedroom A/C Power: On" }, 2: { "function": lambda hass: hass.turn_on("climate.bedroom_ac"), "description": "Bedroom A/C Power: On" }, 3: { "function": lambda hass: hass.turn_off("climate.bedroom_ac"), "description": "Bedroom A/C Power: Off" }, 4: { "function": lambda hass: hass.turn_off("climate.bedroom_ac"), "description": "Bedroom A/C Power: Off" }, }, 2: { # Mode 1: { "function": lambda hass: gree_set_mode(hass,"bedroom_ac","cool"), "description": "Bedroom A/C Mode: Cool" }, 2: { "function": lambda hass: gree_set_mode(hass,"bedroom_ac","heat"), "description": "Bedroom A/C Mode: Heat" }, 3: { "function": lambda hass: gree_set_mode(hass,"bedroom_ac","fan_only"), "description": "Bedroom A/C Mode: Fan" } }, 3: { # Fan Level 1: { "function": lambda hass: gree_set_fan_level(hass,"bedroom_ac","auto"), "description": "Bedroom A/C Fan Level: Auto" }, 2: { "function": lambda hass: gree_set_fan_level(hass,"bedroom_ac","quiet"), "description": "Bedroom A/C Fan Level: Quiet" }, 3: { "function": lambda hass: gree_set_fan_level(hass,"bedroom_ac","medium"), "description": "Bedroom A/C Fan Level: Medium" }, 4: { "function": lambda hass: gree_set_fan_level(hass,"bedroom_ac","high"), "description": "Bedroom A/C Fan Level: High" } }, 4: { # Temperature 1: { "function": lambda hass: set_temperature(hass,"bedroom_ac",72), "description": "Bedroom A/C Temperature: 72" }, 2: { "function": lambda hass: set_temperature(hass,"bedroom_ac",74), "description": "Bedroom A/C Temperature: 74" }, 3: { "function": lambda hass: set_temperature(hass,"bedroom_ac",76), "description": "Bedroom A/C Temperature: 76" }, 4: { "function": lambda hass: set_temperature(hass,"bedroom_ac",78), "description": "Bedroom A/C Temperature: 78" } } } }, 3: { # Fans 1: { # Kitchen 1: {"function": lambda hass: hass.set_value("input_number.kitchen_fan",0)}, 2: {"function": lambda hass: hass.set_value("input_number.kitchen_fan",1)}, 3: {"function": lambda hass: hass.set_value("input_number.kitchen_fan",2)}, 4: {"function": lambda hass: hass.set_value("input_number.kitchen_fan",3)} }, 3: { # Living Room 1: {"function": lambda hass: hass.set_value("input_number.livingroom_fan",0)}, 2: {"function": lambda hass: hass.set_value("input_number.livingroom_fan",1)}, 3: {"function": lambda hass: hass.set_value("input_number.livingroom_fan",2)}, 4: {"function": lambda hass: hass.set_value("input_number.livingroom_fan",3)} }, 4: { # Bedroom 1: {"function": lambda hass: hass.set_value("input_number.bedroom_fan",0)}, 2: {"function": lambda hass: hass.set_value("input_number.bedroom_fan",1)}, 3: {"function": lambda hass: hass.set_value("input_number.bedroom_fan",2)}, 4: {"function": lambda hass: hass.set_value("input_number.bedroom_fan",3)} } } }, 2: { # Music 1: { # Join/unjoin 1: {"function": lambda hass: hass.call_service("sonos/unjoin", entity_id=["media_player.livingroom_sonos","media_player.bedroom_sonos"])}, 3: {"function": lambda hass: hass.call_service("sonos/join", master="media_player.livingroom_sonos",entity_id="media_player.bedroom_sonos")}, 4: {"function": lambda hass: hass.call_service("sonos/join", master="media_player.livingroom_sonos",entity_id="media_player.bedroom_sonos")}, }, 2: { # Play Music 3: { # Living Room Sonos 1: {"function": lambda hass: select_source(hass,"media_player.livingroom_sonos","Songs")}, 2: {"function": lambda hass: select_source(hass,"media_player.livingroom_sonos","Getting Things Done")} }, 4: { # Bedroom Sonos 1: {"function": lambda hass: select_source(hass,"media_player.bedroom_sonos","Songs")}, 2: {"function": lambda hass: select_source(hass,"media_player.bedroom_sonos","Chill sleep")} } }, 3: { # Media Controls 3: { # Living Room Sonos 1: {"function": lambda hass: hass.call_service("media_player/media_pause", entity_id="media_player.livingroom_sonos")}, 2: {"function": lambda hass: hass.call_service("media_player/media_play", entity_id="media_player.livingroom_sonos")}, 3: {"function": lambda hass: hass.call_service("media_player/media_previous_track", entity_id="media_player.livingroom_sonos")}, 4: {"function": lambda hass: hass.call_service("media_player/media_next_track", entity_id="media_player.livingroom_sonos")} }, 4: { # Bedroom Sonos 1: {"function": lambda hass: hass.call_service("media_player/media_pause", entity_id="media_player.bedroom_sonos")}, 2: {"function": lambda hass: hass.call_service("media_player/media_play", entity_id="media_player.bedroom_sonos")}, 3: {"function": lambda hass: hass.call_service("media_player/media_previous_track", entity_id="media_player.bedroom_sonos")}, 4: {"function": lambda hass: hass.call_service("media_player/media_next_track", entity_id="media_player.bedroom_sonos")} } }, 4: { # Options 3: { # Living Room Sonos 2: { # Crossfade 1: {"function": lambda hass: hass.turn_off("switch.livingroom_sonos_crossfade"), "description": "Living Room Sonos: Crossfade: Off"}, 2: {"function": lambda hass: hass.turn_on("switch.livingroom_sonos_crossfade"), "description": "Living Room Sonos: Crossfade: On"} }, 3: { # Shuffle 1: {"function": lambda hass: hass.call_service("media_player/shuffle_set", entity_id="media_player.livingroom_sonos",shuffle=False), "description": "Living Room Sonos: Shuffle: Off"}, 2: {"function": lambda hass: hass.call_service("media_player/shuffle_set", entity_id="media_player.livingroom_sonos",shuffle=True), "description": "Living Room Sonos: Shuffle: On"}, }, 4: { # Repeat 1: {"function": lambda hass: hass.call_service("media_player/repeat_set", entity_id="media_player.livingroom_sonos",repeat="off"), "description": "Living Room Sonos: Repeat: Off"}, 2: {"function": lambda hass: hass.call_service("media_player/repeat_set", entity_id="media_player.livingroom_sonos",repeat="all"), "description": "Living Room Sonos: Repeat: On"}, } }, 4: { # Bedroom Sonos 2: { # Crossfade 1: {"function": lambda hass: hass.turn_off("switch.bedroom_sonos_crossfade"), "description": "Bedroom Sonos: Crossfade: Off"}, 2: {"function": lambda hass: hass.turn_on("switch.bedroom_sonos_crossfade"), "description": "Bedroom Sonos: Crossfade: On"} }, 3: { # Shuffle 1: {"function": lambda hass: hass.call_service("media_player/shuffle_set", entity_id="media_player.bedroom_sonos",shuffle=False), "description": "Bedroom Sonos: Shuffle: Off"}, 2: {"function": lambda hass: hass.call_service("media_player/shuffle_set", entity_id="media_player.bedroom_sonos",shuffle=True), "description": "Bedroom Sonos: Shuffle: On"}, }, 4: { # Repeat 1: {"function": lambda hass: hass.call_service("media_player/repeat_set", entity_id="media_player.bedroom_sonos",repeat="off"), "description": "Bedroom Sonos: Repeat: Off"}, 2: {"function": lambda hass: hass.call_service("media_player/repeat_set", entity_id="media_player.bedroom_sonos",repeat="all"), "description": "Bedroom Sonos: Repeat: On"}, } } } } } ########################### # Action Helper Functions # ########################### def set_brightness(hass, device, brightness): # Convert brightness from percent to 0-255 brightness = brightness * 255 / 100 hass.turn_on(device, brightness=brightness) def set_temperature(hass, device, temperature): hass.call_service("climate/set_temperature",entity_id="climate."+device,temperature=temperature) def gree_set_mode(hass, device, mode): hass.call_service("climate/set_hvac_mode",entity_id="climate."+device,hvac_mode=mode) def gree_set_fan_level(hass, device, level): if (level == "quiet"): hass.turn_on(f"switch.{device}_quiet") else: hass.turn_off(f"switch.{device}_quiet") hass.call_service("climate/set_fan_mode",entity_id="climate."+device,fan_mode=level) def select_source(hass, device, source): hass.call_service("media_player/select_source",entity_id=device,source=source) ############################### # Action Processing Functions # ############################### def check_action(sequence, tree=tree): if (len(sequence) > 0): # Deeper into the rabbit hole category = sequence.pop(0) if (category in tree): return check_action(sequence,tree[category]) else: return False else: # We've the end of the sequence thus far, check if this is the end of a branch # If any of {1..4} exist as keys in tree there's more options return not any(i in tree for i in range(1,4)) def run_action(hass, sequence, tree=tree): if (len(sequence) > 0): # Deeper into the rabbit hole category = sequence.pop(0) if (category in tree): return run_action(hass,sequence,tree[category]) else: hass.log("No match") return False else: # Perform an action from here and log the description if ("function" in tree): tree["function"](hass) else: hass.log("No match") return False if ("description" in tree): hass.log(tree["description"]) else: hass.log(inspect.getsource(tree["function"]).strip()) return True