{"id":26452154,"url":"https://github.com/ageagainstthemachine/circuitpython-program-templates","last_synced_at":"2026-04-18T17:36:49.263Z","repository":{"id":282893958,"uuid":"949743025","full_name":"ageagainstthemachine/CircuitPython-Program-Templates","owner":"ageagainstthemachine","description":"CircuitPython Program Templates","archived":false,"fork":false,"pushed_at":"2025-04-17T13:47:09.000Z","size":64,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-05T23:02:37.655Z","etag":null,"topics":["adafruit-ntp","asyncio","circuitpython","circuitpython-asyncio","circuitpython-project","circuitpython-template","circuitpython-usyslog"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ageagainstthemachine.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}},"created_at":"2025-03-17T04:13:49.000Z","updated_at":"2025-04-17T13:47:13.000Z","dependencies_parsed_at":"2025-04-17T07:24:15.093Z","dependency_job_id":"fbf53033-e8ed-4558-ab57-e5c6f57a3b14","html_url":"https://github.com/ageagainstthemachine/CircuitPython-Program-Templates","commit_stats":null,"previous_names":["ageagainstthemachine/circuitpython-program-templates"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ageagainstthemachine/CircuitPython-Program-Templates","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ageagainstthemachine%2FCircuitPython-Program-Templates","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ageagainstthemachine%2FCircuitPython-Program-Templates/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ageagainstthemachine%2FCircuitPython-Program-Templates/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ageagainstthemachine%2FCircuitPython-Program-Templates/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ageagainstthemachine","download_url":"https://codeload.github.com/ageagainstthemachine/CircuitPython-Program-Templates/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ageagainstthemachine%2FCircuitPython-Program-Templates/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31978574,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T17:30:12.329Z","status":"ssl_error","status_checked_at":"2026-04-18T17:29:59.069Z","response_time":103,"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":["adafruit-ntp","asyncio","circuitpython","circuitpython-asyncio","circuitpython-project","circuitpython-template","circuitpython-usyslog"],"created_at":"2025-03-18T17:39:00.328Z","updated_at":"2026-04-18T17:36:49.243Z","avatar_url":"https://github.com/ageagainstthemachine.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CircuitPython Program Templates\n\n## Overview\n\nThis repository contains a collection of starter templates for CircuitPython projects designed to help you quickly bootstrap new applications. Templates cover a variety of use cases and functionality from asynchronous task management to network connectivity, NTP time synchronization, syslog logging, and memory monitoring - all tailored for resource-constrained devices.\n\nEach template is thoroughly documented and comes with preconfigured settings via a `settings.toml` file.\n\n## Templates Included\n\n- **Asyncio Program Template:**  \n  A robust asynchronous framework featuring:\n  - Conditional Wi-Fi connectivity\n  - Time synchronization using NTP with hybrid DST support (USA and non-USA)\n  - Dual logging (console and optional remote syslog with additional library)\n  - Memory monitoring\n  - Modular configuration via `settings.toml`\n\n### `asyncio` Program Template Details\n\n#### Key Features\n\n- **Modular \u0026 Configurable:**  \n  Easily enable/disable features (Wi-Fi, NTP, syslog, etc.) by editing `settings.toml`.\n  \n- **Asynchronous Operation:**  \n  Leverage Python's `asyncio` to run multiple concurrent tasks without blocking, making it straightforward to add new functionality without disturbing existing code.\n\n- **Common Features Pre-Integrated:**  \n  Wi-Fi, NTP time synchronization, logging, and more are already implemented so it's east to just jump right in and add new tasks for your own functionality.\n\n- **Dynamic Library Loading:**  \n  If you don't need Wi-Fi, disable it in the `settings.toml` file and the library won't even load. The same thing goes for all of the optional functionality in the template.\n  \n- **Thorough Documentation:**  \n  Both the code and configuration files include detailed comments to help you understand and customize each part of the template.\n  \n- **Tested Platforms:**  \n  The code has been tested on:\n  - **Raspberry Pi Pico W (RP2040)**\n  - **Raspberry Pi Pico 2 W (RP2350)**\n  \n- **Open Source:**  \n  Distributed under the GPL-3.0 License.\n\n#### Minimum Required Libraries\n\nFor this template to run correctly, please ensure that the following libraries are installed in the `lib` directory or present in the firmware build (some of these are included in the official CircuitPython bundle):\n\n- **Standard Libraries (built-in):**\n  - `os` (used for reading the settings.toml file)\n  - `gc` (garbage collection)\n  - `asyncio` (run multiple tasks concurrently)\n  - `time` (for handling time)\n  - `rtc` (for handling time updates to internal RTC)\n  - `wifi` (connect to wireless networks)  \n  - `socketpool` (network socket management)\n  \n- **Additional CircuitPython Libraries:**\n  - **Time Synchronization:**  \n    - `adafruit_ntp` (used for synchronizing time via NTP)\n  - **(Optional) Remote Logging:**  \n    - A syslog client library (e.g., [`usyslog`](https://github.com/ageagainstthemachine/circuitpython-usyslog)) if you wish to enable remote syslog logging.\n\n*Note:* Some of these libraries are available as part of the [CircuitPython Bundle](https://circuitpython.org/libraries) provided by Adafruit. Make sure you are using a version of CircuitPython that supports `asyncio` (v9.x or later is recommended).\n\n#### Getting Started\n\n1. **Clone the Repository:**\n    - bash: git clone, etc.\n\n2. **Copy Files to Your Board:**\n   - Copy the template's `code.py` to the root directory of your board.\n   - Copy the accompanying `settings.toml` file to your board as well.\n\n3. **Configure Settings:**\n   - Open `settings.toml` and adjust the parameters (e.g., Wi-Fi SSID/PSK, NTP settings) to suit your environment and use case.\n\n4. **Run the Program:**\n   - Once the files are in place, the program will do the following things:\n     - Attempt to connect to Wi-Fi (if enabled)\n     - Synchronize time using NTP (with optional DST adjustments and server configurability)\n     - Start the main asynchronous tasks (including a dummy task for demonstration)\n\n#### Code Structure \u0026 Documentation\n\n##### Code Overview\n\n- **Configuration Class:**  \n  Loads settings from `settings.toml` and converts them into easy-to-access environment variables.\n  \n- **Logging \u0026 Diagnostics:**  \n  The `structured_log()` function provides uniform logging to the console and (optionally) a remote syslog server. Memory usage is periodically monitored using `monitor_memory()`. Note: syslog functionality requires a separate library (e.g., [`usyslog`](https://github.com/ageagainstthemachine/circuitpython-usyslog)).\n\n- **Network Connectivity:**  \n  Contains both a synchronous Wi-Fi connection function and an asynchronous task that continuously monitors and re-establishes connectivity.\n\n- **Time Synchronization:**  \n  Utilizes `adafruit_ntp` for fetching the current UTC time, applies the base timezone offset, and dynamically (or statically) adjusts for DST.\n\n- **Task Management:**  \n  Demonstrates how to structure asynchronous tasks using `asyncio`. The `dummy_task()` serves as an example of a periodic task.\n\n##### Adding New Tasks\n\nTo add a new asynchronous task:\n\n1. **Define Your Task:**  \n   Create an async function (note: see the `dummy_task()` for an example) to encapsulate your new functionality.\n\n2. **Integrate with the Main Loop:**  \n   In the `main()` function, add your new task to the tasks list:\n   ```python\n   tasks.append(asyncio.create_task(your_new_task()))\n   ```\n\n3. **Logging \u0026 Error Handling:**  \n   Use `structured_log()` to record key events and errors in a unified manner. Optionally, incorporate memory monitoring during critical operations using `monitor_memory()`.\n\n#### Configuration Settings\n\nBelow is a detailed explanation of the configurable settings available in `settings.toml`:\n\n##### Network Configuration\n\n- **WIFI_ENABLED**  \n  *Value:* `\"TRUE\"` or `\"FALSE\"`  \n  *Description:* Enables or disables Wi-Fi connectivity. When enabled, the program will attempt to connect using the provided SSID and PSK.\n\n- **SSID**  \n  *Value:* Your Wi-Fi network's SSID (e.g., `\"Your_SSID\"`)  \n  *Description:* The identifier for your Wi-Fi network. Note that this is required when `WIFI_ENABLED` is set to `\"TRUE\"`.\n\n- **PSK**  \n  *Value:* Your Wi-Fi network password (e.g., `\"Your_PSK\"`)  \n  *Description:* The pre-shared key (password) required to connect to your Wi-Fi network.\n\n##### NTP (Time Synchronization) Configuration\n\n- **NTP_ENABLED**  \n  *Value:* `\"TRUE\"` or `\"FALSE\"`  \n  *Description:* Enables or disables the NTP time synchronization task. When enabled, the program fetches the current time from an NTP server.\n\n- **NTP_OFFSET**  \n  *Value:* A numerical value representing the timezone offset in hours (e.g., `\"-8\"`)  \n  *Description:* The base timezone offset to be applied to UTC time.\n\n- **NTP_SYNC_INTERVAL**  \n  *Value:* A numerical value indicating the interval (in seconds) for synchronizing time (e.g., `\"3600\"`)  \n  *Description:* Determines how frequently the NTP sync task updates the time.\n\n##### DST (Daylight Savings Time) Configuration\n\n- **DST_ENABLED**  \n  *Value:* `\"TRUE\"` or `\"FALSE\"`  \n  *Description:* Enables or disables DST adjustments. When disabled, DST corrections are not applied, and `is_dst()` always returns `False`.\n\n- **DST_MODE**  \n  *Value:* `\"dynamic\"` or `\"static\"`  \n  *Description:*  \n  - **Dynamic:** Computes DST boundaries based on U.S. rules (second Sunday in March to the first Sunday in November).  \n  - **Static:** Uses the provided `DST_START` and `DST_END` values.\n\n- **DST_OFFSET**  \n  *Value:* An integer representing the additional hour offset during DST (e.g., `1`)  \n  *Description:* The extra offset applied during DST.\n\n- **DST_START**  \n  *Value:* A string in the format `\"MM-DD HH:MM\"` (e.g., `\"03-14 02:00\"`)  \n  *Description:* The static start time for DST (used if `DST_MODE` is not set to `\"dynamic\"`).\n\n- **DST_END**  \n  *Value:* A string in the format `\"MM-DD HH:MM\"` (e.g., `\"11-07 02:00\"`)  \n  *Description:* The static end time for DST (used if `DST_MODE` is not set to `\"dynamic\"`).\n\n- **NTP_SERVER**  \n  *Value:* A string representing the NTP server address (leave empty for library-included default, e.g., `\"pool.ntp.org\"`)  \n  *Description:* Specifies a custom NTP server for time synchronization.\n\n##### Syslog \u0026 Diagnostics Configuration\n\n- **SYSLOG_SERVER_ENABLED**  \n  *Value:* `\"TRUE\"` or `\"FALSE\"`  \n  *Description:* Enables or disables remote syslog logging. When enabled, logs are sent to the specified syslog server.\n\n- **SYSLOG_SERVER**  \n  *Value:* A string containing the syslog server address (e.g., `\"10.0.0.10\"`)  \n  *Description:* The IP address or hostname of the syslog server.\n\n- **SYSLOG_PORT**  \n  *Value:* A numerical value indicating the port (e.g., `\"514\"`)  \n  *Description:* The port number to be used for syslog communication.\n\n- **MEMORY_MONITORING**  \n  *Value:* `\"TRUE\"` or `\"FALSE\"`  \n  *Description:* When enabled, the program periodically logs memory usage details for diagnostic purposes.\n\n- **CONSOLE_LOG_ENABLED**  \n  *Value:* `\"TRUE\"` or `\"FALSE\"`  \n  *Description:* When enabled, log messages are output to the console. This is useful for real-time debugging and troubleshooting.\n\n#### Troubleshooting\n\nIf you encounter issues while running the template, consider the following checks:\n\n- **Wi-Fi Connectivity:**  \n  - Ensure that `WIFI_ENABLED` is set to `\"TRUE\"` in `settings.toml`.  \n  - Verify that `SSID` and `PSK` are correctly configured for your network.\n  \n- **Time Synchronization Issues:**  \n  - Confirm that `NTP_ENABLED` is `\"TRUE\"` and `NTP_SERVER` is either left empty (to use the default) or set to a reachable server.  \n  - Check that `NTP_OFFSET` and `NTP_SYNC_INTERVAL` are correctly set for your timezone and desired update frequency.\n  - If you're using DST adjustments, verify that `DST_ENABLED` is `\"TRUE\"` and that `DST_MODE`, `DST_OFFSET`, `DST_START`, and `DST_END` reflect your preferred DST configuration.\n\n- **Logging \u0026 Diagnostics:**  \n  - If no logs appear on your console, ensure `CONSOLE_LOG_ENABLED` is `\"TRUE\"`.  \n  - For remote logging issues, verify that `SYSLOG_SERVER_ENABLED` is `\"TRUE\"` and that the `SYSLOG_SERVER` and `SYSLOG_PORT` values are correct, as well as the library is present on your board in the lib folder.\n  - Enable `MEMORY_MONITORING` and console logging if you suspect resource constraints might be affecting performance or functionality.\n\n- **General Debugging:**  \n  - Review the comments in both `code.py` and `settings.toml` for guidance on how each setting affects program behavior.\n  - Ensure that your CircuitPython version is compatible (v9.x or later is recommended).\n\n---\n\n#### FAQ\n\nTBD\n\n#### Known Issues\n\n- The circuitpython-usyslog support needs to be implemented better (handle log severity levels more explicitly).\n\n#### Fixed Issues\n\n- Incorrect timestamps in syslog messages - fixed in [this commit](https://github.com/ageagainstthemachine/CircuitPython-Program-Templates/pull/4/commits/023f6803964a5ca90b0e088f538a97da04f0c231).\n- WiFi connection errors result in unhandled exception - fixed in [this commit](https://github.com/ageagainstthemachine/CircuitPython-Program-Templates/commit/5e79f58c31436721180801bdbc912d5492274718).\n\n#### Contributing\n\nContributions are encouraged. If you have improvements, additional templates, or new features, please submit a pull request. When contributing, please abide by the following:\n\n- Follow the established code style and commenting conventions.\n- Update the documentation where necessary.\n- Ensure compatibility with the tested platforms.\n\nNote: If you successfully test this on a board/platform other than the RPi Pico W and 2 W, please let me know!\n\n#### License\n\nThis project is licensed under the **GPL-3.0 License**. See the [LICENSE](LICENSE) file for further details.\n\n#### Disclaimer\n\nThis project is provided \"as-is\" without any warranties. Like everything else on the internet, use at your own risk.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fageagainstthemachine%2Fcircuitpython-program-templates","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fageagainstthemachine%2Fcircuitpython-program-templates","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fageagainstthemachine%2Fcircuitpython-program-templates/lists"}