{"id":35101409,"url":"https://github.com/bbartling/icalender-to-bacnet","last_synced_at":"2026-05-21T11:02:09.976Z","repository":{"id":325825786,"uuid":"1102488585","full_name":"bbartling/icalender-to-bacnet","owner":"bbartling","description":"Concept idea to create a generic icalender to BACnet gateway.","archived":false,"fork":false,"pushed_at":"2025-11-23T16:04:23.000Z","size":90,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"develop","last_synced_at":"2025-11-23T17:29:12.183Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/bbartling.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":"2025-11-23T14:57:27.000Z","updated_at":"2025-11-23T16:04:28.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/bbartling/icalender-to-bacnet","commit_stats":null,"previous_names":["bbartling/icalender-to-bacnet"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/bbartling/icalender-to-bacnet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbartling%2Ficalender-to-bacnet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbartling%2Ficalender-to-bacnet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbartling%2Ficalender-to-bacnet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbartling%2Ficalender-to-bacnet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bbartling","download_url":"https://codeload.github.com/bbartling/icalender-to-bacnet/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbartling%2Ficalender-to-bacnet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33298255,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-21T02:57:32.698Z","status":"ssl_error","status_checked_at":"2026-05-21T02:57:31.990Z","response_time":62,"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":[],"created_at":"2025-12-27T16:59:54.948Z","updated_at":"2026-05-21T11:02:09.971Z","avatar_url":"https://github.com/bbartling.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# icalender-to-bacnet\nConcept idea to create a generic icalender to BACnet gateway.\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e🐍 Python Setup\u003c/summary\u003e\n\nCreate a virtual environment:\n```bash\npython -m venv .venv\nsource .venv/bin/activate\n```\nPackages:\n```bash\npip install requests icalendar recurring-ical-events python-dateutil tzdata bacpypes3\n```\n\n### Args\n\n```bash\npython scripts/ical_event_test.py \\\n    --url \"YOUR_ICS_URL\" \\\n    --tz America/Chicago \\\n    --max-events 10 \\\n    --poll-minutes 0\n```\n\nUseful options:\n\n* `--poll-minutes 10` → check feed every 10 minutes\n* `--no-debug` → quiet mode\n* `--window-days 180` → expand events farther ahead\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e🧪 Test With Google’s US Holiday Calendar\u003c/summary\u003e\n\n\nRun the test script which also works fine on Windows in PowerShell:\n\n```bash\npython scripts/ical_event_test.py --url \"https://calendar.google.com/calendar/ical/en.usa%23holiday%40group.v.calendar.google.com/public/basic.ics\"\n```\n\nYou will see the US Holidays from Googles calender:\n\n```text\nPOLL #1 at 2025-11-23 09:27:31 CST\n[DEBUG] HTTP status: 200\n[DEBUG] Downloaded 121366 bytes.\n\n=== Upcoming Events ===\n\nNext 10 events:\n------------------------------------------------------------\n 1. Thanksgiving Day\n    When: 2025-11-27 00:00 CST\n    Ends: 2025-11-28 00:00 CST\n    In:   3d 14h 32m\n    Dur:  1440 min\n\n 2. Black Friday\n    When: 2025-11-28 00:00 CST\n    Ends: 2025-11-29 00:00 CST\n    In:   4d 14h 32m\n    Dur:  1440 min\n\n 3. Christmas Eve\n    When: 2025-12-24 00:00 CST\n    Ends: 2025-12-25 00:00 CST\n    In:   30d 14h 32m\n    Dur:  1440 min\n\n 4. Christmas Day\n    When: 2025-12-25 00:00 CST\n    Ends: 2025-12-26 00:00 CST\n    In:   31d 14h 32m\n    Dur:  1440 min\n\n 5. New Year's Eve\n    When: 2025-12-31 00:00 CST\n    Ends: 2026-01-01 00:00 CST\n    In:   37d 14h 32m\n    Dur:  1440 min\n\n 6. New Year's Day\n    When: 2026-01-01 00:00 CST\n    Ends: 2026-01-02 00:00 CST\n    In:   38d 14h 32m\n    Dur:  1440 min\n\n 7. Martin Luther King Jr. Day\n    When: 2026-01-19 00:00 CST\n    Ends: 2026-01-20 00:00 CST\n    In:   56d 14h 32m\n    Dur:  1440 min\n\n 8. Valentine's Day\n    When: 2026-02-14 00:00 CST\n    Ends: 2026-02-15 00:00 CST\n    In:   82d 14h 32m\n    Dur:  1440 min\n\n 9. Presidents' Day\n    When: 2026-02-16 00:00 CST\n    Ends: 2026-02-17 00:00 CST\n    In:   84d 14h 32m\n    Dur:  1440 min\n\n10. Daylight Saving Time starts\n    When: 2026-03-08 00:00 CST\n    Ends: 2026-03-09 00:00 CDT\n    In:   104d 14h 32m\n    Dur:  1440 min\n\n------------------------------------------------------------\nNext event begins in: 3d 14h 32m\n```\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e🗓️ Run a test on your own ICS calender\u003c/summary\u003e\n\nTo get your own ICS URL from Google Calendar:\n\n1. Calendar Settings → **Integrate Calendar**\n2. Copy **Secret address in iCal format**\n   (Treat this like a password)  \n\n![Leave Temp Snip](https://github.com/bbartling/icalender-to-bacnet/blob/develop/googleSnip.png)  \n\nI made an additional Testing Schedule on my personal Google account which is a recurring event named `Occupied`:  \n\n![Leave Temp Snip](https://github.com/bbartling/icalender-to-bacnet/blob/develop/bensTestCalenderSnip.png)  \n\nTested on Windows in PowerShell:\n\n```\n\u003e python scripts/ical_event_test.py --url \"https://calendar.google.com/calendar/ical/4d67f1779bf6d9c1c1e3615a449f2f2469d0d4aa0136faa16a7eeebd0ae1ebbe%40group.calendar.google.com/private-d58ed4b8a80b7356cbac2e74ae596c0a/basic.ics\"\n\nPOLL #1 at 2025-11-23 09:53:04 CST\n[DEBUG] HTTP status: 200\n[DEBUG] Downloaded 957 bytes.\n\n=== Upcoming Events ===\n\nNext 10 events:\n------------------------------------------------------------\n 1. Occupied\n    When: 2025-11-24 08:00 CST\n    Ends: 2025-11-24 17:00 CST\n    In:   22h 6m\n    Dur:  540 min\n\n 2. Occupied\n    When: 2025-11-25 08:00 CST\n    Ends: 2025-11-25 17:00 CST\n    In:   1d 22h 6m\n    Dur:  540 min\n\n 3. Occupied\n    When: 2025-11-26 08:00 CST\n    Ends: 2025-11-26 17:00 CST\n    In:   2d 22h 6m\n    Dur:  540 min\n\n 4. Occupied\n    When: 2025-11-27 08:00 CST\n    Ends: 2025-11-27 17:00 CST\n    In:   3d 22h 6m\n    Dur:  540 min\n\n 5. Occupied\n    When: 2025-11-28 08:00 CST\n    Ends: 2025-11-28 17:00 CST\n    In:   4d 22h 6m\n    Dur:  540 min\n\n 6. Occupied\n    When: 2025-12-01 08:00 CST\n    Ends: 2025-12-01 17:00 CST\n    In:   7d 22h 6m\n    Dur:  540 min\n\n 7. Occupied\n    When: 2025-12-02 08:00 CST\n    Ends: 2025-12-02 17:00 CST\n    In:   8d 22h 6m\n    Dur:  540 min\n\n 8. Occupied\n    When: 2025-12-03 08:00 CST\n    Ends: 2025-12-03 17:00 CST\n    In:   9d 22h 6m\n    Dur:  540 min\n\n 9. Occupied\n    When: 2025-12-04 08:00 CST\n    Ends: 2025-12-04 17:00 CST\n    In:   10d 22h 6m\n    Dur:  540 min\n\n10. Occupied\n    When: 2025-12-05 08:00 CST\n    Ends: 2025-12-05 17:00 CST\n    In:   11d 22h 6m\n    Dur:  540 min\n\n------------------------------------------------------------\nNext event begins in: 22h 6m\n\n```\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e🤖 Run the BACnet Gateway (POC)\u003c/summary\u003e\n\n\n* ***NOT FINISHED PROOF OF CONCEPT***\n\nThis launches a minimal BACnet server that:\n\n* builds a **weekly BACnet ScheduleObject** from iCal events\n* exposes **next event timestamp**\n* exposes **next event state (BinaryValue)**\n* periodically refreshes from the ICS feed\n\nRun it:\n\n```bash\npython scripts/ical_to_bacnet_gateway.py \\\n    --name \"iCal-BACnet-GW\" \\\n    --instance 12345 \\\n    --url \"YOUR_ICS_URL\" \\\n    --tz America/Chicago \\\n    --poll-minutes 10 \\\n    --debug\n```\n\n### Key flags\n\n| Flag             | Description                                        |\n| ---------------- | -------------------------------------------------- |\n| `--name`         | BACnet device name                                 |\n| `--instance`     | BACnet device instance number                      |\n| `--address`      | Optional local bind, e.g. `10.200.200.50/24:47808` |\n| `--url`          | ICS feed URL                                       |\n| `--tz`           | Timezone for event interpretation                  |\n| `--poll-minutes` | How often to refresh ICS feed                      |\n| `--debug`        | Enable debug logging                               |\n\n---\n\n## 📡 BACnet Objects Exposed\n\nWhen scanning with YABE, BAC0, BACnet Explorer, or Niagara, you should discover:\n\n### 1. **Schedule,1**\n\n* `objectName = \"ical-schedule\"`\n* `weeklySchedule` built from repeating/expanded iCal events\n* `presentValue` reflects current active state\n\n### 2. **Analog Value,10** → `\"next-event-time\"`\n\n* `presentValue` = **UNIX timestamp** for next event start\n* Useful for sequencing or triggering transitions\n\n### 3. **Binary Value,10** → `\"next-event-state\"`\n\n* `presentValue` = **ACTIVE / INACTIVE**\n* Currently assumes:\n\n  * ACTIVE → occupied\n  * INACTIVE → unoccupied\n\nIf the iCal feed has no future events:\n\n* schedule remains \"unoccupied\"\n* next-event values revert to defaults\n\n\u003c/details\u003e\n\n---\n\n## 📜 License\n\nEverything here is **MIT Licensed** — free, open source, and made for the BAS community.  \nUse it, remix it, or improve it — just share it forward so others can benefit too. 🥰🌍\n\n\n【MIT License】\n\nCopyright 2025 Ben Bartling\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbbartling%2Ficalender-to-bacnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbbartling%2Ficalender-to-bacnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbbartling%2Ficalender-to-bacnet/lists"}