{"id":42794103,"url":"https://github.com/vdbg/hubibot","last_synced_at":"2026-01-30T00:23:20.785Z","repository":{"id":42461964,"uuid":"432046820","full_name":"vdbg/hubibot","owner":"vdbg","description":"telegram robot for Hubitat","archived":false,"fork":false,"pushed_at":"2025-12-14T23:57:25.000Z","size":141,"stargazers_count":2,"open_issues_count":3,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-12-17T13:17:01.572Z","etag":null,"topics":["hubitat","python","telegram","telegram-bot"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vdbg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-11-26T03:50:34.000Z","updated_at":"2025-12-14T23:57:21.000Z","dependencies_parsed_at":"2024-12-12T01:23:24.363Z","dependency_job_id":null,"html_url":"https://github.com/vdbg/hubibot","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/vdbg/hubibot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdbg%2Fhubibot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdbg%2Fhubibot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdbg%2Fhubibot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdbg%2Fhubibot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vdbg","download_url":"https://codeload.github.com/vdbg/hubibot/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdbg%2Fhubibot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28891389,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-29T21:06:44.224Z","status":"ssl_error","status_checked_at":"2026-01-29T21:06:42.160Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hubitat","python","telegram","telegram-bot"],"created_at":"2026-01-30T00:23:20.291Z","updated_at":"2026-01-30T00:23:20.778Z","avatar_url":"https://github.com/vdbg.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![GitHub issues](https://img.shields.io/github/issues/vdbg/hubibot.svg)](https://github.com/vdbg/hubibot/issues)\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/vdbg/hubibot/main/LICENSE)\n\n# HubiBot: Telegram robot for Hubitat\n\nThis program allows a [Telegram](https://telegram.org/) user to issue commands against devices managed by [Hubitat](https://hubitat.com/) through a Telegram bot.\n\nNotable pros compared to alternatives are fine-grained access control and not requiring a VPN.\n\n## Highlights\n\n* Can issue commands to Hubitat devices by talking to a Telegram robot, e.g., `/on Office Light` to turn on the device named \"Office Light\".\n* Can issue different types of command: on/off, lock/unlock, open/close, dim, ...\n* Can get the status, capabilities and history of a device.\n* Can give multiple names to devices, e.g., `/on hw` doing the same as `/on Hot Water`.\n* Can act on multiple devices at once, e.g., `/on hw, office` to turn on both  \"Hot Water\" and \"Office Light\".\n* Can query and change Hubitat's mode or security monitor state, e.g. `/mode home` and `/arm home`.\n* Can expose different sets of devices and permissions to different groups of people, e.g., person managing Hubitat, family members and friends.\n\n\n## Example of interaction\n\n\n\u003cimg width=\"479\" alt=\"hubi1\" src=\"https://user-images.githubusercontent.com/1063918/158442236-b4811fc1-a2bc-486b-adf2-3bf8e02ab591.PNG\"\u003e\n\n\u003cimg width=\"475\" alt=\"hubi2\" src=\"https://user-images.githubusercontent.com/1063918/158442306-eaec3b2b-009d-49d3-bc06-b8652148f80d.PNG\"\u003e\n\n\n## Pre-requisites\n\n* A [Hubitat](https://hubitat.com/) hub\n* A device, capable of running either Docker containers or Python, that is on the same LAN as the hub e.g., [Raspbian](https://www.raspbian.org/) or Windows\n* [Maker API](https://docs.hubitat.com/index.php?title=Maker_API) app installed and configured in Hubitat\n* A [Telegram](https://telegram.org/) account to interact with the bot\n* A Telegram [bot](https://core.telegram.org/bots). Use [BotFather](https://core.telegram.org/bots#6-botfather) to create one\n\n## Installing\n\nThe app reads the settings from `template.config.yaml`, then `config.yaml` (if it exists), then environment variables\nin the form `HUBIBOT_KEY=value`, then command line parameters in the form `HUBIBOT_KEY=value`.\n\nIn both cases value needs to be valid JSON compatible with the entries in `template.config.yaml`, e.g. `123`, `'string'`, `[ 'a', 'list', 'of', 'string']`, etc.  \n\nThe absolute path to the config file can be set via the `HUBIBOT_CONFIG_FILE` environment variable if it cannot be collocated with template.config.yaml.\n\nEnvironment variables can be especially useful docker environments, such as [TrueNAS via Launch Docker Image](https://www.truenas.com/docs/scale/scaletutorials/apps/docker/). All environment variables consumed by the app are all caps and prefixed with `HUBIBOT_`. \n\n\nAt the minimum, you'll need to specify the telegram and hubitat tokens, enable one user group (and put a valid user in it) and enable one device group. Assuming no config file, the minimal workable command-line incantation with debug logs enabled will look something like:\n\n```\npython main.py \\\n  \"HUBIBOT_MAIN_LOGVERBOSITY='DEBUG'\" \\\n  \"HUBIBOT_TELEGRAM_TOKEN='8419043u1:fcdklasednfow8124'\" \\\n  \"HUBIBOT_TELEGRAM_ENABLED_USER_GROUPS=['admins']\" \\\n  \"HUBIBOT_TELEGRAM_USER_GROUPS_ADMINS_IDS=[ 123456 ]\" \\\n  \"HUBIBOT_HUBITAT_ENABLED_DEVICE_GROUPS=['all']\"  \\\n  \"HUBIBOT_HUBITAT_URL='http://hubitat.local/'\" \\\n  \"HUBIBOT_HUBITAT_APPID=51\" \\\n  \"HUBIBOT_HUBITAT_TOKEN='fa763de0-9d0b-11ee-8c90-0242ac120002'\"\n```\n\nAnd, assuming the config file is not used, the minimal workable docker setup will look something like:\n\n```\nsudo docker run -d \\\n  --name my_hubibot \\\n  -e \"HUBIBOT_MAIN_LOGVERBOSITY='DEBUG'\" \\\n  -e \"HUBIBOT_TELEGRAM_TOKEN='8419043u1:fcdklasednfow8124'\" \\\n  -e \"HUBIBOT_TELEGRAM_ENABLED_USER_GROUPS=['admins']\" \\\n  -e \"HUBIBOT_TELEGRAM_USER_GROUPS_ADMINS_IDS=[ 123456 ]\" \\\n  -e \"HUBIBOT_HUBITAT_ENABLED_DEVICE_GROUPS=['all']\"  \\\n  -e \"HUBIBOT_HUBITAT_URL='http://hubitat.local/'\" \\\n  -e \"HUBIBOT_HUBITAT_APPID=51\" \\\n  -e \"HUBIBOT_HUBITAT_TOKEN='fa763de0-9d0b-11ee-8c90-0242ac120002'\" \\\n  vdbg/hubibot:latest\n```\n\nAnd a command line version adding an extra user group and device group:\n\n```\npython main.py \\\n  \"HUBIBOT_TELEGRAM_TOKEN='8419043u1:fcdklasednfow8124'\" \\\n  \"HUBIBOT_MAIN_LOGVERBOSITY='DEBUG'\" \\\n  \"HUBIBOT_TELEGRAM_ENABLED_USER_GROUPS=['admins','family']\" \\\n  \"HUBIBOT_TELEGRAM_USER_GROUPS_ADMINS_IDS=[ 123 ]\" \\\n  \"HUBIBOT_TELEGRAM_USER_GROUPS_FAMILY_IDS=[ 456 ]\" \\\n  \"HUBIBOT_TELEGRAM_USER_GROUPS_FAMILY_ACCESS_LEVEL='SECURITY'\" \\\n  \"HUBIBOT_TELEGRAM_USER_GROUPS_FAMILY_DEVICE_GROUPS=['regular']\" \\\n  \"HUBIBOT_HUBITAT_ENABLED_DEVICE_GROUPS=['all','regular']\"  \\\n  \"HUBIBOT_HUBITAT_URL='http://hubitat.local/'\" \\\n  \"HUBIBOT_HUBITAT_APPID=51\" \\\n  \"HUBIBOT_HUBITAT_TOKEN='fa763de0-9d0b-11ee-8c90-0242ac120002'\"\n  \"HUBIBOT_HUBITAT_DEVICE_GROUPS_REGULAR_ALLOWED_DEVICE_IDS=[]\" \\\n  \"HUBIBOT_HUBITAT_DEVICE_GROUPS_REGULAR_REJECTED_DEVICE_IDS=[ 302, 487, 522 ]\"\n```\n\nSee `template.config.yaml` for more details on configuration options.\n\nTo install, choose one of these 3 methods (using config file in these examples):\n\n### Using pre-built Docker image\n\nDependency: Docker installed.\n\n1. `touch config.yaml`\n2. This will fail due to malformed config.yaml. That's intentional :)\n   ``sudo docker run --name my_hubibot -v \"`pwd`/config.yaml:/app/config.yaml\" vdbg/hubibot``\n3. `sudo docker cp my_hubibot:/app/template.config.yaml config.yaml`\n4. Edit `config.yaml` by following the instructions in the file\n5. `sudo docker start my_hubibot -i -e HUBIBOT_MAIN_LOGVERBOSITY=DEBUG`\n  This will display logging on the command window allowing for rapid troubleshooting. `Ctrl-C` to stop the container if `config.yaml` is changed\n7. When done testing the config:\n  * `sudo docker container rm my_hubibot`\n  * ``sudo docker run -d --name my_hubibot -v \"`pwd`/config.yaml:/app/config.yaml\" --restart=always --memory=100m vdbg/hubibot``\n  * To see logs: `sudo docker container logs -f my_hubibot`\n\n### Using Docker image built from source\n\nDependency: Docker installed.\n\n1. `git clone https://github.com/vdbg/hubibot.git`\n2. `sudo docker build -t hubibot_image hubibot`\n3. `cd hubibot`\n4. `cp template.config.yaml config.yaml`\n5. Edit `config.yaml` by following the instructions in the file\n6. Test run: ``sudo docker run --name my_hubibot -v \"`pwd`/config.yaml:/app/config.yaml\" hubibot_image``\n   This will display logging on the command window allowing for rapid troubleshooting. `Ctrl-C` to stop the container if `config.yaml` is changed\n7. If container needs to be restarted for testing: `sudo docker start my_hubibot -i`\n8. When done testing the config:\n  * `sudo docker container rm my_hubibot`\n  * ``sudo docker run -d --name my_hubibot -v \"`pwd`/config.yaml:/app/config.yaml\" --restart=always --memory=100m hubibot_image``\n  * To see logs: `sudo docker container logs -f my_hubibot`\n\n### Running directly on the device\n\nDependency: [Python](https://www.python.org/) 3.11+ and pip3 installed.\n\n1. `git clone https://github.com/vdbg/hubibot.git`\n2. `cd hubibot`\n3. `cp template.config.yaml config.yaml`\n4. Edit `config.yaml` by following the instructions in the file\n5. `pip3 install -r requirements.txt`\n6. Run the program:\n  * Interactive mode: `python3 main.py`\n  * Shorter: `.\\main.py` (Windows) or `./main.py` (any other OS).\n  * As a background process (on non-Windows OS): `python3 main.py \u003e log.txt 2\u003e\u00261 \u0026`\n7. To exit: `Ctrl-C` if running in interactive mode, `kill` the process otherwise.\n\n## Using the bot\n\nFrom your Telegram account, write `/h` to the bot to get the list of available commands.\n\n## Understanding user and device groups\n\nUser and device groups allow for fine-grained access control, for example giving access to different devices to parents, kids, friends and neighbors.\n\nWhile three user groups (\"admins\", \"family\", \"guests\") and three device groups (\"all\",\"regular\",\"limited\") are provided in the template config file as examples, any number of user and device groups are supported (names are free-form, alphabetical). If only one single user is using the bot, only keeping \"admins\" user group \u0026 \"all\" device group will suffice.\n\nDevice groups represent collection of Hubitat devices that can be accessed by user groups. In the template config file \"admins\" user group has access to \"all\" device group, \"family\" to \"regular\", and \"guests\" to \"limited\".\n\nUser groups represent collection of Telegram users that have access to device groups. User groups can contain any number of Telegram user ids (those with no user ids are ignored) and reference any number of device groups. User groups with an `access_level` set to:\n* `NONE`: cannot use any commands. Useful to disable a user group.\n* `DEVICE`: can use device commands e.g., `/list`, `/regex`, `/on`, `/off`, `/open`, `/close`, `/dim`, `/status`, `/info`.\n* `SECURITY`: can use the same commands as `access_level: DEVICE`, and also act on locks with `/lock` \u0026 `/unlock` commands, the `/arm` command for [Hubitat Safety Monitor](https://docs.hubitat.com/index.php?title=Hubitat%C2%AE_Safety_Monitor_Interface), the `/mode` command to view and change the mode, the `/events` command to see a device's history, and the `/tz` command to change the timezone for `/events` and `/lastevent`.\n* `ADMIN`: can use the same commands as `access_level: SECURITY`, and also admin commands e.g., `/users`, `/groups`, `/refresh`, `/exit`. In addition some commands have more detailed output (e.g., `/list`, `/status`).\n\nA user can only belong to one user group, but a device can belong to multiple device groups and a device group can be referenced by multiple user groups.\n\n## Device name resolution\n\nFor all commands taking in device names (such as : `/on name of device`), the app will:\n\n1. Split the input using the `device_name_separator` setting in `config.yaml` and remove all leading/trailing spaces. \n  For example, \"  office light,   bedroom  \" becomes \"office light\", \"bedroom\"\n2. Look for these in the list of devices Hubitat exposes through MakerAPI that are accessible to the current user (see previous section). \n  If the `case_insensitive` setting in `config.yaml` is set to `true`, then the case doesn't need to match.\n  For example \"office light\" will be resolved to \"Office Light\"\n3. For devices not found, the bot will try and interpret the input as a regex. For example, \"(Office|Bedroom) Light\" will resolve to both \"Office Light\" and \"Bedroom Light\"\n4. For devices still not found, the transforms in the `device` setting under `aliases` section in `config.yaml` are tried in order.\n  For example, the app will transform \"bedroom\" to \"bedroom light\" and look for that name\n5. If there are entries that still could not be found, the entire name resolution process fails.\n\n## Difference between /list and /regex\n\n* `/list` uses the filter as a substring.\n* `/regex` uses the filter as a regex.\n\n## Troubleshooting\n\n* Set `logverbosity` under `main` to `DEBUG` in `config.yaml` to get more details. Note: **Hubitat's token is printed in plain text** when `logverbosity` is `DEBUG`\n* Ensure the bot was restarted after making changes to `config.yaml`\n* Ensure the device running the Python script can access the Hubitat's Maker API by trying to access `\u003curl\u003e/apps/api/\u003cappid\u003e/devices?access_token=\u003ctoken\u003e` url from that device (replace placeholders with values from `hubitat` section in config.yaml)\n* If a given device doesn't show up when issuing the `/list` command:\n  1. Check that it is included in the list of devices exposed through Hubitat's MakerAPI\n  2. Check that the `device_groups:\u003cname\u003e:allowed_device_ids` setting in `config.yaml` for the device group(s) of the current user is either empty or includes the device's id\n  3. If the device was added to MakerAPI after starting the bot, issue the `/refresh` command\n  4. Check the device group(s) of the given user with the `/users` command\n  5. Check that the device has a label in Hubitat in addition to a name. The former is used by the bot\n\n## Getting Telegram user Ids\n\nThe `config.yaml` file takes user Ids instead of user handles because the later are neither immutable nor unique.\n\nThere are two methods for getting a Telegram user Id:\n1. Ask that user to write to the @userinfobot to get their user Id\n2. Ensure `logVerbosity` under `main` is set to `WARNING` or higher in `config.yaml` and ask that user to write to the bot. There will be a warning in the logs with that user's Id and handle.\n\n## Authoring\n\nStyle:\n\n* From command line: `pip3 install black`,\n* In VS code: Settings,\n    * Text Editor, Formatting, Format On Save: checked\n    * Python, Formatting, Provider: `black`\n    * Python, Formatting, Black Args, Add item: `--line-length=200`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvdbg%2Fhubibot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvdbg%2Fhubibot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvdbg%2Fhubibot/lists"}