You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hass-4button/actions.py

560 lines
25 KiB

#!/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