{"id":35405059,"url":"https://github.com/joachimda/modbus-to-x","last_synced_at":"2026-03-06T22:08:44.411Z","repository":{"id":290447564,"uuid":"974443092","full_name":"joachimda/modbus-to-x","owner":"joachimda","description":"ESP32 based hardware and firmware stack that bridges modbus RTU devices to modern network services.","archived":false,"fork":false,"pushed_at":"2026-02-09T20:44:18.000Z","size":20202,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-10T00:07:39.182Z","etag":null,"topics":["esp32","modbus-rtu","mqtt"],"latest_commit_sha":null,"homepage":"","language":"C++","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/joachimda.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-04-28T19:35:29.000Z","updated_at":"2026-02-09T20:44:22.000Z","dependencies_parsed_at":"2025-12-08T00:08:09.717Z","dependency_job_id":null,"html_url":"https://github.com/joachimda/modbus-to-x","commit_stats":null,"previous_names":["joachimda/modbus-to-x"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/joachimda/modbus-to-x","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joachimda%2Fmodbus-to-x","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joachimda%2Fmodbus-to-x/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joachimda%2Fmodbus-to-x/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joachimda%2Fmodbus-to-x/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joachimda","download_url":"https://codeload.github.com/joachimda/modbus-to-x/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joachimda%2Fmodbus-to-x/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30200756,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T19:07:06.838Z","status":"ssl_error","status_checked_at":"2026-03-06T18:57:34.882Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: 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":["esp32","modbus-rtu","mqtt"],"created_at":"2026-01-02T12:39:30.182Z","updated_at":"2026-03-06T22:08:44.365Z","avatar_url":"https://github.com/joachimda.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Modbus-to-X\n\nAn ESP32-based hardware and firmware stack that bridges RS-485/Modbus field devices to modern network services such as MQTT, with a configuration-first UX for installers and maintainers.\n\n## Table of Contents\n- [Overview](#overview)\n- [Architecture](#architecture)\n  - [Hardware](#hardware)\n  - [Firmware](#firmware)\n- [Getting Started](#getting-started)\n  - [Prerequisites](#prerequisites)\n  - [Build and Flash](#build-and-flash)\n  - [Release Automation](#release-automation)\n  - [Local UI Development](#local-ui-development)\n- [Usage](#usage)\n  - [First Boot and Network Setup](#first-boot-and-network-setup)\n  - [Configuring Modbus Devices](#configuring-modbus-devices)\n  - [MQTT Publishing](#mqtt-publishing)\n- [Project Structure](#project-structure)\n  - [Hardware Documentation](#hardware-documentation)\n  - [Software Documentation](#software-documentation)\n- [Acknowledgements](#acknowledgements)\n\n## Overview\nModbus-to-X combines a custom ESP32 carrier board with firmware that polls Modbus RTU devices over RS-485, persists telemetry locally, and republishes structured payloads to MQTT brokers. \nThe firmware exposes an onboard web interface for Wi-Fi provisioning, Modbus configuration, live device statistics, and log retrieval so field technicians can deploy the gateway without recompiling binaries.\n\n## Architecture\nThe project is split between dedicated hardware design files and a PlatformIO firmware project. Hardware-specific documentation lives in [`hardware/`](hardware/); firmware, tooling, and UI assets live in [`software/`](software/).\n\n### Hardware\n- Four-layer ESP32 carrier featuring an ESP32-WROOM-32D module, MAX3485 RS-485 transceiver\n- RJ12 Connector exposing differential RS-485 pair alongside field power for quick deployment.\n- Wide input voltage range (4.5 - 40V)\n- Supporting assets include datasheets, fabrication rules, and release notes for each board revision under `hardware/`.\n\n### Firmware\n- PlatformIO-based ESP32 application primarily built with the Arduino framework.\n- Library dependencies: ModbusMaster, PubSubClient, ArduinoJson, and ESPAsyncWebServer for protocol handling and a dynamic UI backend.\n- A custom partition table separates user configurations from UI components, leaving user configurations untouched on filesystem uploads.\n- Boot sequence mounts filesystem partitions, starts the async web server (\"MBX Server\"), initializes the Modbus scheduler, and spins up the MQTT manager.\n- Configuration data for the Modbus bus, devices, and MQTT settings is stored in `/conf/*.json` on the dedicated config SPIFFS partition (`cfg`) and hot-reloaded without reflashing.\n- MQTT passwords are stored in NVS preferences; `/conf/mqtt.json` contains non-sensitive fields.\n- Default wiring, RS-485 guard times, Wi-Fi AP Portal credentials, and OTA parameters are centralized in [`Config.h`](software/modbus-to-mqtt/include/Config.h).\n\n## Getting Started\n\n### Prerequisites\n- Modbus-to-X hardware (v0.2 alpha or later) and Modbus RTU devices wired to the RS-485 terminals.\n- 4.5–40 VDC field power (buck input validated in the current design) and a USB-to-UART adapter if not using OTA uploads.\n- Development host with Python 3, [PlatformIO Core](https://platformio.org/install/cli), and a working `git` toolchain. Required Python build dependencies are installed automatically by `scripts/install_build_deps.py` when PlatformIO runs.【F:software/modbus-to-mqtt/scripts/install_build_deps.py†L1-L32】\n\n### Build and Flash\n1. Clone the repository and enter the firmware workspace:\n   ```bash\n   git clone https://github.com/joachimda/modbus-to-x.git\n   cd modbus-to-x/software/modbus-to-mqtt\n   ```\n2. Choose an environment in `platformio.ini`:\n   - `prod-board-v0-1-alpha` targets the custom board with OTA uploads enabled by default.\n3. Build the firmware (PlatformIO will fetch dependencies and embed git metadata):\n   ```bash\n   pio run\n   ```\n4. Flash via USB/UART or OTA depending on the selected environment:\n   ```bash\n   # Serial upload (comment upload_protocol, upload_port and upload_flags)\n   pio run -e prod-board-v0-1-alpha -t upload\n\n   # OTA upload to a provisioned gateway (uncomment upload_protocol, upload_port and upload_flags)\n   pio run -e prod-board-v0-1-alpha -t upload\n   ```\n5. Upload the web UI and config assets to SPIFFS when they change:\n   ```bash\n   pio run -e prod-board-v0-1-alpha -t uploadfs\n   ```\n\n### Release Automation\nPushing a `v*` tag triggers the GitHub Actions workflow in `.github/workflows/main.yml` to build firmware + filesystem images and create a GitHub Release with the assets:\n- `modbus-to-x.bin` (firmware)\n- `modbus-to-x.fs.bin` (filesystem)\n- `modbus-to-x.manifest.json` (includes SHA-256 hashes and a signature generated from `OTA_SIGNING_KEY_PEM` and `KID`).\n\n### Local UI Development\nThe `scripts/run_test_webserver.py` helper serves the `data/` directory with mocked API responses so you can iterate on the HTML/JS bundle without flashing the device:\n```bash\ncd software/modbus-to-mqtt\npython scripts/run_test_webserver.py\n# Visit http://127.0.0.1:8000\n```\nIt injects correct MIME types, disables caching, and emulates `/api/stats/system`, `/api/events`, `/api/logs`, and `/api/system/reboot` for the SPA.\n\n## Usage\n\n### First Boot and Network Setup\n1. Power the gateway; it will advertise a Wi-Fi AP using the defaults defined in `Config.h` (`MODBUS-MQTT-BRIDGE` / `you-shall-not-pass`).\n2. Connect to the AP. The ESP will try getting 192.168.4.1 from DHCP. If supported on your OS, you will be prompted to open the Captive Portal and redirected automatically. If these fail, check your router for the device's IP address, and use your browser to open the configuration page `http://192.168.4.1/`. \n3. Follow the on-screen guidance to scan, join, or provision hidden networks, optionally specifying static IP parameters before saving.\n4. After a successful network connection is established, reboot the device.\n\n### Configuring Modbus Devices\n- Use **Configure Modbus** to edit the RS-485 bus, add devices, and define datapoints. Modbus configurations are stored in the config partition at `/conf/config.json` and can be applied live without rebooting.\n- Configuration files follow the schema in `data/conf/schema.json` (UI) and the example in `docs/configuration_examples/modbus.json`. Each datapoint specifies the function code, register address, data type, scale, and engineering units that will be published when polled.\n- Per-device MQTT publishing and Home Assistant discovery can be toggled in the Modbus config; discovery publishes retained entity definitions for read/write datapoints.\n  Example (excerpt):\n  ```json\n  {\n    \"devices\": [\n      {\n        \"name\": \"Boiler\",\n        \"slaveId\": 10,\n        \"mqttEnabled\": true,\n        \"homeassistantDiscoveryEnabled\": true,\n        \"dataPoints\": [\n          {\n            \"id\": \"temp\",\n            \"name\": \"Temperature\",\n            \"function\": 4,\n            \"address\": 100,\n            \"numOfRegisters\": 1,\n            \"dataType\": \"int16\",\n            \"scale\": 0.1,\n            \"unit\": \"C\",\n            \"topic\": \"plant/boiler/temp_c\"\n          }\n        ]\n      }\n    ]\n  }\n  ```\n\n### MQTT Publishing\n- Configure broker host, port, credentials, and optional root topic via the **Configure MQTT** page or by editing `/conf/mqtt.json`. The firmware automatically extracts hostnames from URLs and persists the MQTT password in NVS preferences.\n- When Modbus reads succeed, datapoint values are published to MQTT using either the per-datapoint topic override or the default pattern `\u003croot\u003e/\u003cdevice\u003e/\u003cdatapointId\u003e` with slugified datapoint names as datapoint IDs.\n- MQTT connectivity, Modbus statistics, and recent logs are visible on the dashboard.\n\n## Project Structure\n```\n.\n├── hardware/                 # Schematics, PCB layout, BOM assets, release notes\n├── software/\n│   └── modbus-to-mqtt/       # PlatformIO workspace with firmware, web UI, and tooling\n└── README.md                 # This high-level overview\n```\n\n### Hardware Documentation\nDetailed hardware notes, KiCad sources, datasheets, and per-revision release notes are kept in [`hardware/`](hardware/). Start with the latest folder under [`hardware/releases/`](hardware/releases/) (for example, `v0.2-alpha`) for the current board spin and consult the KiCad project in [`hardware/kicad_files/`](hardware/kicad_files/) for schematics, layout, and fabrication outputs.\n\n### Software Documentation\nThe firmware entry point, reusable libraries, and static assets live under [`software/modbus-to-mqtt/`](software/modbus-to-mqtt/). Key references:\n- [`src/`](software/modbus-to-mqtt/src/) – firmware modules for Modbus polling, MQTT connectivity, OTA, and the async web server.\n- [`data/`](software/modbus-to-mqtt/data/) – web UI bundle and config schema served by the device (config data lives in the `/conf` partition at runtime).\n- [`docs/configuration_examples/`](software/modbus-to-mqtt/docs/configuration_examples/) – JSON schemas and examples for Modbus and MQTT configuration.\n- [`boards/`](software/modbus-to-mqtt/boards/) – custom PlatformIO board definition for the production hardware (ESP32, 16 MB flash).\n\n\n## Acknowledgements\n- Built on Espressif's ESP32 platform and the open-source libraries listed in `platformio.ini` (ModbusMaster, PubSubClient, ArduinoJson, ESPAsyncWebServer).\n- Component footprints and 3D models sourced from vendor or third-party libraries included under `hardware/kicad_files/lib/` with accompanying license terms in `hardware/kicad_files/lib/licenses`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoachimda%2Fmodbus-to-x","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoachimda%2Fmodbus-to-x","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoachimda%2Fmodbus-to-x/lists"}