xbar-plugins/hubitat.py
2024-12-31 06:58:20 -05:00

115 lines
3.4 KiB
Python

#!/usr/bin/env python3
# <xbar.title>Hubitat Menu</xbar.title>
# <xbar.version>v1.0</xbar.version>
# <xbar.author>Erick Ruiz de Chavez</xbar.author>
# <xbar.desc>Simple toggle menu for Hubitat devices. Requires the Toggle API App.</xbar.desc>
# <xbar.dependencies>python</xbar.dependencies>
# <xbar.var>string(LIST_DEVICES_URL): List Devices URL. Provided by the Toggle API App.</xbar.var>
# <xbar.var>boolean(USE_INTERNAL_URL=true): Whether to be use the internal or external toggle URL.</xbar.var>
# <xbar.var>boolean(RUN_IN_TERMINAL=false): Whether to run the menu selections in a terminal window. (For debugging purposes).</xbar.var>
# <xbar.var>boolean(SHOW_ICON=true): Whether to show the menu icon on the taskbar.</xbar.var>
# <xbar.var>boolean(SHOW_TEXT=false): Whether to show the menu label on the taskbar.</xbar.var>
import json
import os
import sys
from urllib.request import urlopen
LIST_DEVICES_URL = os.getenv("LIST_DEVICES_URL")
USE_INTERNAL_URL = os.getenv("USE_INTERNAL_URL", "true") == "true"
RUN_IN_TERMINAL = os.getenv("RUN_IN_TERMINAL") == "true"
SHOW_ICON = os.getenv("SHOW_ICON") == "true"
SHOW_TEXT = os.getenv("SHOW_TEXT") == "true"
def log_run(function_name):
with open(".hubitat.log", mode="a", encoding="utf8") as file:
content = f"FUNCTION: {function_name} | ARGS: {', '.join(sys.argv)} | LIST_DEVICES_URL: {LIST_DEVICES_URL} | USE_INTERNAL_URL: {USE_INTERNAL_URL} | RUN_IN_TERMINAL: {RUN_IN_TERMINAL}\n"
file.write(content)
def get_devices(list_devices_url):
log_run("get_devices")
devices = []
with urlopen(list_devices_url) as response:
devices = json.loads(response.read().decode())
return devices
def toggle_device(device_url):
log_run("toggle_device")
urlopen(device_url)
return
def print_menu(items):
log_run("print_menu")
menu_icon = ":house:" if SHOW_ICON else ""
menu_label = "Hubitat" if SHOW_TEXT else ""
menu_space = " " if SHOW_ICON and SHOW_TEXT else ""
menu = menu_space.join([menu_icon, menu_label])
menus = []
menus.append(menu)
menus.append("---")
menus += items
print("\n".join(menus))
def print_devices_menu(devices, use_internal_url, run_in_terminal):
log_run("print_devices_menu")
items = []
for device in devices:
device_name = device["Name"]
device_url = (
device["InternalURL"] if use_internal_url else device["ExternalURL"]
)
script_path = os.path.realpath(__file__)
segments = []
segments.append(device_name)
segments.append(f'shell="{script_path}"')
segments.append(f'param1="{device_url}"')
if run_in_terminal:
segments.append("terminal=true")
items.append(" | ".join(segments))
items.sort()
print_menu(items=items)
def print_error_menu():
log_run("print_error_menu")
print_menu(
items=[
'List Devices URL variable is missing! Please select "Open plugin..." from xbar\'s menu to configure the plugin.'
]
)
def main():
log_run("main")
if len(sys.argv) > 1:
toggle_device(device_url=sys.argv[1])
return
if LIST_DEVICES_URL is None:
print_error_menu()
return
devices = get_devices(list_devices_url=LIST_DEVICES_URL)
print_devices_menu(
devices=devices,
use_internal_url=USE_INTERNAL_URL,
run_in_terminal=RUN_IN_TERMINAL,
)
if __name__ == "__main__":
main()