{"id":50789549,"url":"https://github.com/ankitd013/inknode","last_synced_at":"2026-06-12T10:01:00.087Z","repository":{"id":364244094,"uuid":"1264125883","full_name":"Ankitd013/InkNode","owner":"Ankitd013","description":"A minimalist, zero-distraction E-Paper Smart Dashboard for Raspberry Pi, featuring a Swiss Design UI, local weather forecasting, and MQTT home automation integration.","archived":false,"fork":false,"pushed_at":"2026-06-12T08:43:53.000Z","size":2422,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-12T09:21:04.977Z","etag":null,"topics":["captive-portal","dashboard","e-paper","flask","home-automation","iot","mqtt","python","raspberry-pi","raspberry-pi-zero","smart-home","waveshare","weather-station"],"latest_commit_sha":null,"homepage":"https://inknode.clawiz.com","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Ankitd013.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":"2026-06-09T15:28:08.000Z","updated_at":"2026-06-12T08:43:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Ankitd013/InkNode","commit_stats":null,"previous_names":["ankitd013/inknode"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/Ankitd013/InkNode","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ankitd013%2FInkNode","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ankitd013%2FInkNode/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ankitd013%2FInkNode/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ankitd013%2FInkNode/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ankitd013","download_url":"https://codeload.github.com/Ankitd013/InkNode/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ankitd013%2FInkNode/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34238714,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["captive-portal","dashboard","e-paper","flask","home-automation","iot","mqtt","python","raspberry-pi","raspberry-pi-zero","smart-home","waveshare","weather-station"],"created_at":"2026-06-12T10:00:38.732Z","updated_at":"2026-06-12T10:01:00.081Z","avatar_url":"https://github.com/Ankitd013.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n[![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-orange.svg)](https://www.gnu.org/licenses/agpl-3.0)\n[![Python](https://img.shields.io/badge/Python-3.13+-blue.svg)](https://www.python.org/)\n[![Hardware](https://img.shields.io/badge/Hardware-Raspberry_Pi-c2185b.svg)](https://www.raspberrypi.org/)\n\n\u003cimg src=\"assets/logo.svg\" alt=\"InkNode Logo\" width=\"300\" /\u003e\n\n\u003ch3 align=\"center\"\u003eA clean, distraction-free room climate monitor and home automation dashboard for the Raspberry Pi\u003c/h3\u003e\n\u003c/div\u003e\n\n\u003cimg src=\"assets/inknode-screen.png\" alt=\"InkNode Screen\"/\u003e\n\n## 📖 What is InkNode?\n\nInkNode gives you complete visibility into your home environment without adding another glowing screen to your life. If you want smart home data on your desk or nightstand but are tired of bright backlights, InkNode is the solution. It is a self-contained appliance that reads local ambient conditions via hardware sensors, pulls outdoor forecasts, and displays them on a calm, paper-like electronic ink display.\n\nOperating as an independent node, it provides a local web interface for effortless configuration and streams live telemetry directly to your existing home automation server over MQTT.\n\n## ✨ Core Pillars of InkNode\n\nTo deliver a seamless and calm experience, InkNode is built on three main principles: Distraction-Free Design, Frictionless Setup, and Flexible Architecture.\n\n### Distraction-Free Design\n- **High-Contrast, Swiss-Style UI:** A borderless layout inspired by classic minimalist design prioritizes clean typography and readability.\n\n- **Smart Color Layering:** Intentionally utilizes the e-paper's red ink for abstract weather icons and metric labels (`WIND`, `HUM`), preserving heavy black ink for critical data.\n\n\n### Frictionless Setup (Zero Headaches)\n\n- **Automated Headless Provisioning:** Forget about plugging in a monitor, keyboard, or manually editing configuration files on an SD card.\n\n- **Captive Setup Portal:** If InkNode cannot reach the internet on boot, it automatically launches a temporary Wi-Fi Access Point and displays a QR code on the e-paper screen. Scan it, enter your credentials in the local web portal, and you are online.\n\n- **Safe Rollbacks:** If a connection to your router fails, a background thread safely aborts and restores the setup portal so you are never locked out of your device.\n    \n### Flexible Architecture\n- **Local Web Dashboard:** Tweak geographic coordinates, customize panel headers, or update MQTT broker targets directly from your browser.\n\n- **Hot Reloading:** Saving changes automatically updates the system environment (`.env`) and restarts background loops immediately—no reboot required.\n\n- **Hardware Agnostic (HAL):** Display and sensor logic are cleanly isolated. You can easily swap the default 2.9\" Waveshare drivers or AHTx0 code to support alternative I2C sensors (like the BME280) or different display sizes.\n\n- **Pre-Deployment Testing:** Test layout calculations and logic on your PC using mocked hardware states before deploying to a physical Raspberry Pi.\n\n### 📡 Decoupled Hardware \u0026 Automation\n\n-   **Hardware Agnostic (HAL):** The core display and sensor handling logic are cleanly isolated in `hal_display.py` and `hal_sensors.py`. You can easily swap out the default 2.9\" Waveshare drivers or the AHTx0 code to support completely different display sizes or alternative I2C sensors (like the BME280 or DHT22).\n    \n-   **Pre-Deployment Testing:** Includes an independent test runner (`run_tests.py`) that uses mocked hardware states. This lets you test the layout calculations and application logic on a standard PC before deploying the code to a physical Pi.\n    \n## ⚙️ System Architecture: Under the Hood\n\nInkNode manages simultaneous background processes while ensuring the UI remains responsive and independent of network or hardware delays.\n\n```mermaid\ngraph TD\n    %% Styling\n    classDef script fill:#1f1f1f,stroke:#E63946,stroke-width:2px,color:#fff;\n    classDef hardware fill:#e1dbcd,stroke:#333,stroke-width:2px,color:#000;\n    classDef external fill:#fbfbfb,stroke:#0052cc,stroke-width:1px,color:#000;\n\n    %% Elements\n    BOOT[boot_manager.py]:::script\n    CONF[config.py]:::script\n    DASH[dashboard.py / Flask]:::script\n    MQTT[mqtt_engine.py]:::script\n    WEATH[weather_api.py]:::script\n    \n    SENS[hal_sensors.py]:::script\n    DISP[hal_display.py]:::script\n    WAVE[waveshare_epd]:::script\n    \n    AHT[AHT10/20 Hardware Sensor]:::hardware\n    EPD[2.9 inch E-Paper Screen]:::hardware\n    \n    OM[Open-Meteo API]:::external\n    BROK[MQTT Broker / Home Assistant]:::external\n    BROW[User Web Browser]:::external\n\n    %% Flow Layout\n    BOOT --\u003e|1. Reads profiles| CONF\n    \n    %% Boot Decision Fork\n    BOOT --\u003e|2. Tests Network Connection| CHECK{Internet Available?}\n    \n    CHECK --\u003e|No| PORTAL[Launch Captive AP Portal]\n    PORTAL --\u003e|Draws Onboarding QR| DISP\n    BROW \u003c--\u003e|Configures Wi-Fi via Port 80| DASH\n    DASH --\u003e|Writes updates \u0026 reboots| CONF\n    \n    CHECK --\u003e|Yes| RUN[Initialize Runtime Engines]\n    \n    %% Runtime Concurrent Engines\n    subgraph Background Execution Threads\n        RUN --\u003e DASH\n        RUN --\u003e MQTT\n    end\n\n    %% Data Harvesting Interconnectivity\n    DASH \u003c--\u003e|Inter-process State| BOOT\n    SENS --\u003e|Polls Raw Data via I2C| AHT\n    WEATH --\u003e|Fetches Live Forecast via HTTPS| OM\n    \n    %% Aggregation\n    BOOT --\u003e|Requests Updates| SENS\n    BOOT --\u003e|Requests Updates| WEATH\n    \n    %% Output Routing\n    BOOT --\u003e|Composes Geometric Canvas| DISP\n    DISP --\u003e|Low-Level SPI Calls| WAVE\n    WAVE --\u003e|Refreshes Matrix Layers| EPD\n    \n    MQTT --\u003e|Publishes Formatted JSON| BROK\n    BROW \u003c--\u003e|Manages Settings / Dynamic .env| DASH\n```\n\n## 🛠️ Hardware Specifications \u0026 Wiring\n\n### What You Need\n\nTo build a standalone InkNode device, gather the following components:\n\n1. **Raspberry Pi** Zero W or Zero 2W (ideal for a compact footprint).\n\n2. **Waveshare 2.9\" E-Paper Module:** Must be the Black/White/Red Tri-Color version.\n\n3. **AHT25 or AHT20 Sensor:** I2C digital temperature and humidity module.\n\n4. **MicroSD Card:** 8GB or larger running Raspberry Pi OS Lite (32/64-bit).\n\n### Wiring Diagram\n\nConnect your Waveshare 2.9inch e-Paper Module (B) to your Raspberry Pi using the physical SPI pin layout mapped below.\n\n(For complete technical specifications, refer directly to the [Official Waveshare 2.9inch e-Paper Module (B) Manual.](https://www.waveshare.com/wiki/2.9inch_e-Paper_Module_(B)_Manual))\n\n```mermaid\ngraph LR\n    %% Styling Configuration\n    classDef epaper fill:#fff,stroke:#E63946,stroke-width:2px,color:#000;\n    classDef rpi fill:#1f1f1f,stroke:#c2185b,stroke-width:2px,color:#fff;\n    classDef pwr fill:#ffcccc,stroke:#cc0000,stroke-width:1px,color:#000;\n    classDef gnd fill:#e1e1e1,stroke:#666,stroke-width:1px,color:#000;\n    classDef spi fill:#e1f5fe,stroke:#03a9f4,stroke-width:1px,color:#000;\n    classDef ctrl fill:#e8f5e9,stroke:#4caf50,stroke-width:1px,color:#000;\n\n    subgraph Waveshare 2.9in Module B Pi Hat / Cable\n        VCC[VCC - 3.3V / Red Wire]:::pwr\n        GND_E[GND - Ground / Black Wire]:::gnd\n        DIN[DIN - SPI MOSI / Blue Wire]:::spi\n        CLK[CLK - SPI SCLK / Yellow Wire]:::spi\n        CS[CS - Chip Select / Orange Wire]:::spi\n        DC[DC - Data/Command / Green Wire]:::ctrl\n        RST[RST - Reset / White Wire]:::ctrl\n        BUSY[BUSY - Status / Purple Wire]:::ctrl\n    end\n\n    subgraph Raspberry Pi 40-Pin GPIO Header\n        P3V3[3.3V Power - Physical Pin 1]:::pwr\n        PGND[GND Ground - Physical Pin 6]:::gnd\n        BCM10[BCM 10 / MOSI - Physical Pin 19]:::spi\n        BCM11[BCM 11 / SCLK - Physical Pin 23]:::spi\n        BCM8[BCM 8 / CE0 - Physical Pin 24]:::spi\n        BCM25[BCM 25 - Physical Pin 22]:::ctrl\n        BCM17[BCM 17 - Physical Pin 11]:::ctrl\n        BCM24[BCM 24 - Physical Pin 18]:::ctrl\n    end\n\n    %% Wiring Connections\n    VCC  \u003c===\u003e |Power Rail| P3V3\n    GND_E \u003c===\u003e |Ground Reference| PGND\n    DIN  \u003c---\u003e |Data Input| BCM10\n    CLK  \u003c---\u003e |Clock Input| BCM11\n    CS   \u003c---\u003e |Chip Selection| BCM8\n    DC   \u003c---\u003e |Data/Command Control| BCM25\n    RST  \u003c---\u003e |External Reset| BCM17\n    BUSY \u003c---\u003e |Busy Status Output| BCM24\n```\n\n## 🚀 Getting Started\n\n### 1. Enable Hardware Interfaces\n\nEnsure the necessary hardware communication buses are active on your Raspberry Pi.\n\n1. Run `sudo raspi-config` in your terminal.\n\n2. Navigate to Interface Options.\n\n3. Enable both `SPI` and `I2C`\n\n### 2. Install and Execute\n\nClone the repository and run the setup script to install dependencies and configure the environment automatically.\n\n```bash\ngit clone https://github.com/Ankitd013/InkNode.git\ncd InkNode\n\nchmod +x setup.sh\nsudo ./setup.sh\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fankitd013%2Finknode","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fankitd013%2Finknode","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fankitd013%2Finknode/lists"}