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()