From 5bffebad928777d504e5b147de78e61828fe1370 Mon Sep 17 00:00:00 2001 From: erick Date: Tue, 31 Dec 2024 06:58:20 -0500 Subject: [PATCH] Add hubitat.py --- hubitat.py | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 hubitat.py diff --git a/hubitat.py b/hubitat.py new file mode 100644 index 0000000..6609374 --- /dev/null +++ b/hubitat.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 + +# Hubitat Menu +# v1.0 +# Erick Ruiz de Chavez +# Simple toggle menu for Hubitat devices. Requires the Toggle API App. +# python +# string(LIST_DEVICES_URL): List Devices URL. Provided by the Toggle API App. +# boolean(USE_INTERNAL_URL=true): Whether to be use the internal or external toggle URL. +# boolean(RUN_IN_TERMINAL=false): Whether to run the menu selections in a terminal window. (For debugging purposes). +# boolean(SHOW_ICON=true): Whether to show the menu icon on the taskbar. +# boolean(SHOW_TEXT=false): Whether to show the menu label on the taskbar. + +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()