Compare commits

...

2 Commits

Author SHA1 Message Date
Eduard Iten f9d4a3b971 docs: Restructure and internationalize documentation 2025-06-30 17:49:22 +02:00
Eduard Iten 0fd6466d81 Added planning 2025-06-30 17:25:32 +02:00
10 changed files with 342 additions and 6 deletions

16
README.de.md Normal file
View File

@ -0,0 +1,16 @@
# Modulares Bewässerungssystem
Dieses Projekt realisiert ein smartes, modulares Bewässerungssystem, das über Home Assistant gesteuert wird.
## Dokumentation
Die detaillierte Dokumentation befindet sich im Verzeichnis [`docs/`](./docs/):
* **[Konzept](./docs/concept.de.md)**: Beschreibt die Systemarchitektur, die verwendeten Komponenten und die grundlegenden Design-Entscheidungen.
* **[MODBUS Register](./docs/modbus-registers.de.md)**: Definiert die Register-Map für die Kommunikation mit den Slave-Nodes.
* **[Projektplan](./docs/planning.de.md)**: Enthält den Entwicklungs- und Implementierungsplan.
## Schnellstart
* **Hardware**: Die KiCad-Dateien für die Hardware befinden sich im Verzeichnis [`hardware/`](./hardware/).
* **Software**: Die Zephyr-basierte Firmware für die Slave-Nodes befindet sich im Verzeichnis [`software/`](./software/).

View File

@ -1,2 +1,18 @@
# Home assistant irrigation system
This is a home assistant irrigation system
[🇩🇪 Deutsch](README.de.md) | [🇬🇧 English](README.md)
# Modular Irrigation System
This project implements a smart, modular irrigation system controlled via Home Assistant.
## Documentation
The detailed documentation can be found in the [`docs/`](./docs/) directory:
* **[Concept](./docs/concept.en.md)**: Describes the system architecture, the components used, and the basic design decisions.
* **[MODBUS Registers](./docs/modbus-registers.en.md)**: Defines the register map for communication with the slave nodes.
* **[Project Plan](./docs/planning.en.md)**: Contains the development and implementation plan.
## Quick Start
* **Hardware**: The KiCad files for the hardware are located in the [`hardware/`](./hardware/) directory.
* **Software**: The Zephyr-based firmware for the slave nodes is located in the [`software/`](./software/) directory.

View File

@ -1,3 +1,5 @@
[🇩🇪 Deutsch](concept.de.md) | [🇬🇧 English](concept.en.md)
# Konzept: Modulares Bewässerungssystem
Dieses Dokument beschreibt das Konzept für ein modulares, smartes Bewässerungssystem, das zentral über Home Assistant gesteuert wird.

75
docs/concept.en.md Normal file
View File

@ -0,0 +1,75 @@
[🇩🇪 Deutsch](concept.de.md) | [🇬🇧 English](concept.en.md)
# Concept: Modular Irrigation System
This document describes the concept for a modular, smart irrigation system that is centrally controlled via Home Assistant.
## 1. Architecture Overview
The system is divided into three logical layers to ensure high flexibility and maintainability:
1. **Control Layer (Home Assistant):** All logic, automations, and the user interface reside in Home Assistant. This is the "brain" of the system.
2. **Gateway Layer (ESP32):** A pure protocol translator that acts as a bridge between the home network (WLAN/Thread) and the physical bus system of the plant. It contains no control logic of its own.
3. **Actor/Sensor Layer (Slave Nodes):** Robust, specialized modules that are controlled via a bus and perform the actual tasks (switching valves, reading sensors).
![System Architecture](./img/architecture.en.svg)
## 2. System Components
* **Water Tank:** An IBC container serves as a water reservoir.
* **Water Supply:** A "rain thief" on the downpipe directs rainwater into the tank.
* **Pump:** A pump with an integrated pressure expansion tank provides the necessary water pressure.
* **Actuators:** Motorized 12V ball valves to control the water outlets.
* **Level Sensor (precise):** A `QDY30A` with 4-20mA output and RS485/MODBUS interface for continuous measurement of the water level.
* **Level Sensors (Min/Max):** Optional capacitive sensors (`XKC-Y25-NPN` or similar) as redundant protection against running dry and overflowing.
## 3. Gateway
The central communication interface is implemented as a "dumb" gateway.
* **Hardware:** An `ESP32C6`-based board.
* **Function:** The gateway acts as a transparent **MODBUS TCP/IP to MODBUS RTU converter**. It receives commands from the home network and forwards them to the RS485 bus and vice versa. It does not execute its own control logic.
* **Connection to Home Assistant:** The connection is made via the home network, either via WLAN or in the future possibly via Thread/Matter. In Home Assistant, the official MODBUS integration is used to address the gateway and the slaves behind it directly.
## 4. Slave Nodes
The slave nodes are the working units in the field. To keep the effort low for small series production (e.g. at JLCPCB), a universal board design for all slave types is sought.
* **Microcontroller:** An `STM32G431PB`. Although powerful, it offers all the necessary peripherals (multiple UARTs, ADCs, CAN) and enables a uniform hardware and software design.
* **Peripherals per Node:**
* **Two High-Side Outputs (+12V):** Realized via a `VND7050AJ`. Perfect for controlling the 12V motor valves (`Open`/`Close`). The `Sense` line of the driver is read out via an AD converter to realize an end position detection without physical limit switches by measuring the motor current (motor current at standstill ≈ 0).
* **Two Low-Side Outputs (0V):** Outputs switched via N-channel MOSFETs. Can be used to control 12V LEDs in buttons or to switch the solid-state relay for the pump.
* **Two digital inputs:** Direct, protected inputs on the controller for connecting buttons or the capacitive NPN sensors.
## 5. Bus System: MODBUS-RTU via RS485
MODBUS-RTU is consistently used as the bus system.
* **Reasoning:** This choice is pragmatic, as the level sensor already requires MODBUS. This means that only a single, simple and widespread protocol is required for the entire system.
* **Physical Layer:** The cabling is done via RS485. Commercially available Cat-7 Ethernet cable with RJ45 plugs is used:
* 1 twisted pair for the bus signals `A` and `B`.
* 3 pairs of wires in parallel for `+12V` and `GND` to supply power to the slaves.
## 6. Software
* **Operating System (Slaves):** `Zephyr OS`. It is a modern, powerful real-time operating system that enables a clean and maintainable firmware structure.
* **Logic Implementation:** The entire control logic (e.g. "If level < 20% and day of the week = Monday, then switch on valve 3 for 10 minutes") is mapped exclusively in **Home Assistant** via its automation engine.
### 6.1. Firmware Update of the Slaves (OTA)
The firmware of the slaves can be updated during operation via the bus without the need for direct physical access.
* **Concept:** The `MCUBoot` bootloader is used. This is decoupled from the communication protocol.
* **Procedure:**
1. A script in Home Assistant reads the new firmware file (`firmware.bin`).
2. The script breaks the file down into small data packets and sends them one after the other to the target slave via MODBUS command.
3. The running application on the slave receives these packets and writes them directly to the secondary flash memory ("update slot").
4. After successful transmission, the slave is restarted by command.
5. `MCUBoot` checks the signature of the new image, copies it to the primary slot and starts it.
* **Security:** The new firmware must mark itself as "functional" after starting. If it does not do this (e.g. due to a crash), the previous, stable firmware version is automatically restored by `MCUBoot` on the next restart by the watchdog.
## 7. Safety and Robustness Concepts
* **Fail-Safe Behavior:** Each slave node implements a watchdog. If no valid MODBUS query is received from the gateway over a defined period of time (e.g. 15 seconds), the slave goes into a safe state: all valves are closed and relays (e.g. for the pump) are switched off.
* **Electrical Protection Circuits:** All external interfaces are protected. The RS485 bus lines (`A`/`B`) are protected against overvoltages with TVS diodes on each board. Inputs and outputs receive basic ESD protection.
* **Power Supply:** The 12V bus voltage is regulated on each slave node with an efficient `TPS5430DDAR` step-down converter to the required 3.3V for the microcontroller and the bus drivers.

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -0,0 +1,78 @@
<svg xmlns="http://www.w3.org/2000/svg" width="203.36" height="143.44" version="1.1" viewBox="0 0 203.36 143.44">
<g transform="translate(-2.88 -78.28)">
<g stroke-width=".26458">
<g fill="#fff" stroke="#000">
<rect x="3.14" y="78.54" width="88.9" height="21.16" rx="2" ry="2"/>
<rect x="3.14" y="105.4" width="88.9" height="21.16" rx="2" ry="2"/>
<rect x="3.14" y="132.26" width="88.9" height="21.16" rx="2" ry="2"/>
</g>
<text x="47.59" y="86.9" font-family="sans-serif" font-size="5.64" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
<tspan x="47.59" y="86.9" text-anchor="middle">Control Layer</tspan>
<tspan x="47.59" y="93.45" text-anchor="middle">(Home Assistant)</tspan>
</text>
<text x="47.59" y="113.76" font-family="sans-serif" font-size="5.64" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
<tspan x="47.59" y="113.76" text-anchor="middle">Gateway Layer</tspan>
<tspan x="47.59" y="120.31" text-anchor="middle">(ESP32)</tspan>
</text>
<text x="47.59" y="140.62" font-family="sans-serif" font-size="5.64" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
<tspan x="47.59" y="140.62" text-anchor="middle">Actor/Sensor Layer</tspan>
<tspan x="47.59" y="147.17" text-anchor="middle">(Slaves)</tspan>
</text>
</g>
<path d="m47.59 99.7v5.7m-2.82-2.88h5.64" fill="none" stroke="#000" stroke-linecap="round" stroke-width="1.0583"/>
<path d="m47.59 126.56v5.7m-2.82-2.88h5.64" fill="none" stroke="#000" stroke-linecap="round" stroke-width="1.0583"/>
<g stroke-width=".26458">
<g transform="translate(100.58 -2.64)">
<g fill="#fff" stroke="#000">
<rect x="3.14" y="108.04" width="88.9" height="21.16" rx="2" ry="2"/>
<rect x="3.14" y="134.9" width="88.9" height="21.16" rx="2" ry="2"/>
<rect x="3.14" y="161.76" width="88.9" height="21.16" rx="2" ry="2"/>
<rect x="3.14" y="188.62" width="88.9" height="21.16" rx="2" ry="2"/>
</g>
<text x="47.59" y="118.94" font-family="sans-serif" font-size="5.64" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
<tspan x="47.59" y="118.94" text-anchor="middle">Level Sensor</tspan>
<tspan x="47.59" y="125.49" font-size="4.23" text-anchor="middle">(MODBUS Slave)</tspan>
</text>
<text x="47.59" y="145.8" font-family="sans-serif" font-size="5.64" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
<tspan x="47.59" y="145.8" text-anchor="middle">Valve Control 1</tspan>
<tspan x="47.59" y="152.35" font-size="4.23" text-anchor="middle">(MODBUS Slave)</tspan>
</text>
<text x="47.59" y="172.66" font-family="sans-serif" font-size="5.64" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
<tspan x="47.59" y="172.66" text-anchor="middle">Valve Control n</tspan>
<tspan x="47.59" y="179.21" font-size="4.23" text-anchor="middle">(MODBUS Slave)</tspan>
</text>
<text x="47.59" y="199.52" font-family="sans-serif" font-size="5.64" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
<tspan x="47.59" y="199.52" text-anchor="middle">Pump</tspan>
<tspan x="47.59" y="206.07" font-size="4.23" text-anchor="middle">(switched via Slave)</tspan>
</text>
</g>
<path d="m148.17 132.26v-18.52m-2.82 2.82 2.82-2.82 2.82 2.82" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width=".529"/>
<path d="m148.17 159.12v-18.52m-2.82 2.82 2.82-2.82 2.82 2.82" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width=".529"/>
<path d="m148.17 185.98v-18.52m-2.82 2.82 2.82-2.82 2.82 2.82" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width=".529"/>
<path d="m148.17 212.84v-18.52m-2.82 2.82 2.82-2.82 2.82 2.82" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width=".529"/>
</g>
<g fill="none" stroke="#000" stroke-width=".52917">
<path d="m92.04 89.12h10.58"/>
<path d="m92.04 116h10.58"/>
</g>
<path d="m102.62 89.12v-5.29h45.55v26.45" fill="none" stroke="#000" stroke-width=".52917"/>
<path d="m102.62 116h45.55v-23.8h-45.55z" fill="#fff" stroke="#000" stroke-width=".26458"/>
<text x="125.4" y="100.3" font-family="sans-serif" font-size="4.23" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
<tspan x="125.4" y="100.3" text-anchor="middle">Home Network</tspan>
<tspan x="125.4" y="105.11" text-anchor="middle">(WLAN / Thread)</tspan>
</text>
<text x="125.4" y="114.09" font-family="sans-serif" font-size="4.23" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
<tspan x="125.4" y="114.09" text-anchor="middle">MODBUS TCP/IP</tspan>
</text>
<path d="m102.62 142.84h45.55v-23.8h-45.55z" fill="#fff" stroke="#000" stroke-width=".26458"/>
<text x="125.4" y="127.15" font-family="sans-serif" font-size="4.23" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
<tspan x="125.4" y="127.15" text-anchor="middle">Gateway</tspan>
<tspan x="125.4" y="131.96" text-anchor="middle">(Protocol Translator)</tspan>
</text>
<text x="125.4" y="140.94" font-family="sans-serif" font-size="4.23" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
<tspan x="125.4" y="140.94" text-anchor="middle">MODBUS RTU</tspan>
<tspan x="125.4" y="145.75" text-anchor="middle">(RS485 Bus)</tspan>
</text>
<path d="m92.04 142.84h10.58"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -1,8 +1,6 @@
Gerne, hier ist die finale Version der MODBUS-Register-Definition, die alle unsere Diskussionen und Verfeinerungen berücksichtigt, als kompletter Markdown-Block.
[🇩🇪 Deutsch](modbus-registers.de.md) | [🇬🇧 English](modbus-registers.en.md)
Markdown
# MODBUS Register Map Definition v2.0
# MODBUS Register Map Definition v1.0
## 1. Einleitung

View File

@ -0,0 +1,85 @@
[🇩🇪 Deutsch](modbus-registers.de.md) | [🇬🇧 English](modbus-registers.en.md)
# MODBUS Register Map Definition v1.0
## 1. Introduction
This document defines the MODBUS registers for the universal slave nodes of the irrigation system.
### 1.1. Addressing Philosophy
All registers are defined in a single, continuous list per register type (`Input` or `Holding`). A "Category" column logically assigns the function. The addresses are grouped in blocks to leave room for future extensions and to increase readability.
* **`0x0000 - 0x000F`**: Valve control & status
* **`0x0010 - 0x001F`**: Digital outputs (LEDs / relays)
* **`0x0020 - 0x002F`**: Digital inputs (buttons / sensors)
* **`0x00F0 - 0x00FF`**: General device configuration & status
* **`0x0100 - 0x01FF`**: Firmware update mechanism
### 1.2. Used Function Codes
* **`0x03` (Read Holding Registers):** For reading `4xxxx` registers.
* **`0x04` (Read Input Registers):** For reading `3xxxx` registers.
* **`0x06` (Write Single Register):** For writing a single `4xxxx` register.
* **`0x10` (Write Multiple Registers):** For writing multiple `4xxxx` registers at once.
## 2. Input Registers (3xxxx, Read-Only)
| Address (hex) | Name | Category | Description |
| :--- | :--- | :--- | :--- |
| **0x0000** | `VALVE_STATE_MOVEMENT` | Valve | Combined status register. **High-Byte**: Movement (`0`=Idle, `1`=Opening, `2`=Closing, `3`=Error). **Low-Byte**: State (`0`=Closed, `1`=Open). |
| **0x0001** | `MOTOR_CURRENT_MA` | Valve | Current motor current in milliamperes (mA). |
| **0x0020** | `DIGITAL_INPUTS_STATE` | Inputs | Bitmask of the digital inputs. Bit 0: Input 1, Bit 1: Input 2. `1`=Active. |
| **0x0021** | `BUTTON_EVENTS` | Inputs | Event flags for buttons (Clear-on-Read). Bit 0: Button 1 pressed. Bit 1: Button 2 pressed. |
| **0x00F0** | `FIRMWARE_VERSION_MAJOR_MINOR` | System | e.g. `0x0102` for v1.2. |
| **0x00F1** | `FIRMWARE_VERSION_PATCH` | System | e.g. `3` for v1.2.3. |
| **0x00F2** | `DEVICE_STATUS` | System | `0`=OK, `1`=General error. |
| **0x00F3** | `UPTIME_SECONDS_LOW` | System | Lower 16 bits of the uptime in seconds. |
| **0x00F4** | `UPTIME_SECONDS_HIGH` | System | Upper 16 bits of the uptime. |
| **0x0100** | `FWU_LAST_CHUNK_CRC` | Firmware-Update | Contains the CRC16 of the last data chunk received in the buffer. |
## 3. Holding Registers (4xxxx, Read/Write)
| Address (hex) | Name | Category | Description |
| :--- | :--- | :--- | :--- |
| **0x0000** | `VALVE_COMMAND` | Valve | `1`=Open, `2`=Close, `0`=Stop movement. |
| **0x0001** | `MAX_OPENING_TIME_S` | Valve | Safety timeout in seconds for the opening process. |
| **0x0002** | `MAX_CLOSING_TIME_S` | Valve | Safety timeout in seconds for the closing process. |
| **0x0010** | `DIGITAL_OUTPUTS_STATE` | Outputs | Bitmask for reading and writing the outputs. Bit 0: Output 1, Bit 1: Output 2. `1`=ON, `0`=OFF. |
| **0x00F0** | `WATCHDOG_TIMEOUT_S` | System | Timeout of the fail-safe watchdog in seconds. `0`=Disabled. |
| **0x0100** | `FWU_COMMAND` | Firmware-Update | `1`: **Verify Chunk**: The last transmitted chunk was found to be valid by the client. The slave should now write it to flash. `2`: **Finalize Update**: All chunks have been transmitted. Finalize installation and restart. |
| **0x0101** | `FWU_CHUNK_OFFSET_LOW` | Firmware-Update | Lower 16 bits of the 32-bit offset to which the next chunk is to be written. |
| **0x0102** | `FWU_CHUNK_OFFSET_HIGH` | Firmware-Update | Upper 16 bits of the 32-bit offset. |
| **0x0103** | `FWU_CHUNK_SIZE` | Firmware-Update | Size of the next chunk in bytes (max. 256). |
| **0x0180** | `FWU_DATA_BUFFER` | Firmware-Update | **Start address** of a 128x16-bit buffer (256 bytes). Corresponds to registers `40384` to `40511`. |
## 4. Detailed Firmware Update Process
This process is stateless and robust against transmission errors.
1. **Client:** Selects a chunk (max. 256 bytes) from the firmware file and calculates its CRC16.
2. **Client:** Writes the target offset (e.g. `0`) to `FWU_CHUNK_OFFSET_...` and the size to `FWU_CHUNK_SIZE`.
3. **Client:** Writes the chunk data to the `FWU_DATA_BUFFER` (from address `0x0180`).
4. **Slave:** Receives the data, places it in the RAM buffer and calculates the CRC. The result is provided in `FWU_LAST_CHUNK_CRC` (`30256`).
5. **Client:** Reads `FWU_LAST_CHUNK_CRC` and compares the value with the self-calculated CRC.
* **Error:** Go back to step 3 to send the same chunk again.
* **Success:** Continues with the next step.
6. **Client:** Writes the command `1` ("Verify Chunk") to `FWU_COMMAND` (`40256`).
7. **Slave:** Receives the command, takes the verified chunk from the RAM buffer and writes it to the correct location in the flash memory.
8. **Client:** Continues with the next chunk (back to step 1 with new offset and data).
9. **Last Chunk:** After the last chunk has been transferred and written to flash with command `1`, the client writes the command `2` ("Finalize Update") to `FWU_COMMAND`.
10. **Slave:** Performs final checks and restarts so that MCUBoot can perform the installation.
## Appendix: QDY30A Level Sensor Registers
These registers belong to the external level sensor and can also be addressed on the bus. According to the manufacturer, these are Holding Registers (`4xxxx`) that are read with function code `0x03`.
| Address (hex) | Name | R/W | Description |
| :--- | :--- | :-- | :--- |
| **0x0000** | `NODE_ADDRESS` | R/W | Device address of the sensor (1-255). |
| **0x0001** | `BAUDRATE` | R/W | `0`=1200, `1`=2400, `2`=4800, `3`=9600, `4`=19200, `5`=38400, `6`=57600, `7`=115200. |
| **0x0002** | `UNIT` | R/W | `0`=None, `1`=cm, `2`=mm, `3`=MPa, `4`=Pa, `5`=kPa. |
| **0x0003** | `DECIMAL_PLACES` | R/W | Number of decimal places for the measured value (0-3). |
| **0x0004** | `CURRENT_MEASUREMENT` | R | The scaled measured value as a signed 16-bit integer. |
| **0x0005** | `MEASURING_RANGE_ZERO_POINT` | R/W | Raw value for the zero point of the scale. |
| **0x0006** | `MEASURING_RANGE_END_POINT` | R/W | Raw value for the end point of the scale. |

33
docs/planning.de.md Normal file
View File

@ -0,0 +1,33 @@
[🇩🇪 Deutsch](planning.de.md) | [🇬🇧 English](planning.en.md)
# Projektplan: Modulares Bewässerungssystem
| Abgehakt | Aufgabe | Datum | Bemerkungen |
| :---: | :--- | :--- | :--- |
| ✅ | **Phase 0: Planung & Definition** | | |
| ✅ | Konzept erstellen und finalisieren | 30.06.2025 | Architektur, Komponenten und grundlegende Architektur sind festgelegt. |
| ✅ | MODBUS Register Map definieren | 30.06.2025 | Die "API" der Slaves ist definiert und bildet die Grundlage für die Software-Entwicklung. |
| ☐ | **Phase 1: Slave-Node Prototyp (STM32 Eval-Board)** | | **Ziel:** Ein einzelner Slave wird auf dem Eval-Board zum Leben erweckt. |
| ☐ | 1.1 Entwicklungsumgebung für STM32/Zephyr einrichten | | Toolchain, VS Code, Zephyr-SDK, MCUBoot etc. installieren und ein "Hello World" zum Laufen bringen. |
| ☐ | 1.2 Basis-Firmware für Slave-Node erstellen | | Hardware-Abstraktion (GPIOs, ADC, UART für RS485) implementieren. |
| ☐ | 1.3 MODBUS-RTU Stack auf dem Slave implementieren | | Basierend auf der definierten Register-Map. Zuerst nur lesende Funktionen (Status, Version). |
| ☐ | 1.4 Kernlogik implementieren (z.B. Ventilsteuerung) | | Umsetzung der `VENTIL_ZUSTAND_BEWEGUNG` Logik, Strommessung für Endlagen etc. |
| ☐ | **Phase 2: Verifikation der Slave-Firmware** | | **Ziel:** Nachweisen, dass der Slave sich exakt an die MODBUS-Spezifikation hält. |
| ☐ | 2.1 Slave-Node mit PC via USB-MODBUS-Adapter testen | | **Kritischer Meilenstein.** Mit Tools wie "QModMaster" oder einem Python-Skript die Register lesen & schreiben. Die Slave-Firmware wird so unabhängig vom Gateway validiert. |
| ☐ | 2.2 Firmware-Update Mechanismus testen | | Den kompletten Update-Prozess (Chunking, CRC-Check) mit einem Skript vom PC aus testen. Der Slave schreibt die Firmware dabei vorerst nur in einen ungenutzten RAM-Bereich. |
| ☐ | **Phase 3: Hardware-Design und Prototypenbau** | | **Ziel:** Von der Entwicklung auf dem Eval-Board zum massgeschneiderten PCB. |
| ☐ | 3.1 Schaltplan und PCB-Layout für Slave-Node entwerfen | | Basierend auf den Erfahrungen mit dem Eval-Board. |
| ☐ | 3.2 Prototypen-Platinen bestellen und bestücken | | Z.B. bei JLCPCB. THT-Komponenten (Stecker etc.) selbst löten. |
| ☐ | 3.3 Hardware-Inbetriebnahme des ersten Prototyps | | Spannungen prüfen, Firmware aufspielen und die Tests aus Phase 2 wiederholen, um die Hardware zu validieren. |
| ☐ | 3.4 Flash-Schreibroutine für Firmware-Update implementieren | | Den in Schritt 2.2 im RAM validierten Prozess nun auf den echten Flash-Speicher anwenden. |
| ☐ | **Phase 4: Gateway Entwicklung (ESP32 Eval-Board)** | | **Ziel:** Die Brücke von der RS485-Welt ins Heimnetzwerk bauen. |
| ☐ | 4.1 Gateway-Firmware (ESPHome) erstellen | | Einfaches MODBUS TCP zu RTU Gateway auf dem ESP32C6 Eval-Board aufsetzen. |
| ☐ | 4.2 Gateway mit Slave-Node Prototyp verbinden und testen | | Test der Kette: PC (als MODBUS TCP Client) -> WLAN -> Gateway -> RS485 -> Slave. |
| ☐ | **Phase 5: System-Integration in Home Assistant** | | **Ziel:** Das System "smart" machen. |
| ☐ | 5.1 MODBUS-Integration in Home Assistant konfigurieren | | Anlegen der Sensoren und Entitäten für den Slave-Node in der `configuration.yaml` oder über die UI. |
| ☐ | 5.2 Dashboards und Automationen in HA erstellen | | Visualisierung der Zustände (Ventil, Pumpe etc.) und Erstellen der eigentlichen Bewässerungs-Logik. |
| ☐ | 5.3 Python-Skript für Firmware-Update in HA entwickeln | | Implementierung des Chunk-basierten Uploads als Skript, das aus HA heraus aufgerufen werden kann. |
| ☐ | **Phase 6: Aufbau und Inbetriebnahme** | | **Ziel:** Das fertige System installieren. |
| ☐ | 6.1 Alle benötigten Slave-Nodes aufbauen und testen | | Jeden Slave einzeln mit dem PC via USB-Adapter testen und die MODBUS-Adresse konfigurieren. |
| ☐ | 6.2 System final installieren und verkabeln | | Einbau der Komponenten in den Schuppen, Verkabelung des RS485-Busses. |
| ☐ | 6.3 Gesamtsystemtest und Kalibrierung | | Füllstandsensor kalibrieren, Laufzeiten der Ventile prüfen, Fail-Safe-Verhalten testen. |

33
docs/planning.en.md Normal file
View File

@ -0,0 +1,33 @@
[🇩🇪 Deutsch](planning.de.md) | [🇬🇧 English](planning.en.md)
# Project Plan: Modular Irrigation System
| Done | Task | Date | Remarks |
| :---: | :--- | :--- | :--- |
| ✅ | **Phase 0: Planning & Definition** | | |
| ✅ | Create and finalize concept | 2025-06-30 | Architecture, components and basic architecture are defined. |
| ✅ | Define MODBUS Register Map | 2025-06-30 | The "API" of the slaves is defined and forms the basis for software development. |
| ☐ | **Phase 1: Slave Node Prototype (STM32 Eval-Board)** | | **Goal:** A single slave is brought to life on the eval board. |
| ☐ | 1.1 Set up development environment for STM32/Zephyr | | Install toolchain, VS Code, Zephyr-SDK, MCUBoot etc. and get a "Hello World" running. |
| ☐ | 1.2 Create basic firmware for slave node | | Implement hardware abstraction (GPIOs, ADC, UART for RS485). |
| ☐ | 1.3 Implement MODBUS-RTU stack on the slave | | Based on the defined register map. Initially only read functions (status, version). |
| ☐ | 1.4 Implement core logic (e.g. valve control) | | Implementation of the `VALVE_STATE_MOVEMENT` logic, current measurement for end positions etc. |
| ☐ | **Phase 2: Verification of the Slave Firmware** | | **Goal:** Prove that the slave adheres exactly to the MODBUS specification. |
| ☐ | 2.1 Test slave node with PC via USB-MODBUS adapter | | **Critical milestone.** Read & write the registers with tools like "QModMaster" or a Python script. The slave firmware is thus validated independently of the gateway. |
| ☐ | 2.2 Test firmware update mechanism | | Test the complete update process (chunking, CRC check) with a script from the PC. The slave initially only writes the firmware to an unused RAM area. |
| ☐ | **Phase 3: Hardware Design and Prototype Construction** | | **Goal:** From development on the eval board to a customized PCB. |
| ☐ | 3.1 Design schematic and PCB layout for slave node | | Based on the experience with the eval board. |
| ☐ | 3.2 Order and assemble prototype boards | | E.g. at JLCPCB. Solder THT components (connectors etc.) yourself. |
| ☐ | 3.3 Hardware commissioning of the first prototype | | Check voltages, upload firmware and repeat the tests from phase 2 to validate the hardware. |
| ☐ | 3.4 Implement flash write routine for firmware update | | Apply the process validated in RAM in step 2.2 to the real flash memory. |
| ☐ | **Phase 4: Gateway Development (ESP32 Eval-Board)** | | **Goal:** Build the bridge from the RS485 world to the home network. |
| ☐ | 4.1 Create gateway firmware (ESPHome) | | Set up a simple MODBUS TCP to RTU gateway on the ESP32C6 eval board. |
| ☐ | 4.2 Connect and test gateway with slave node prototype | | Test the chain: PC (as MODBUS TCP client) -> WLAN -> Gateway -> RS485 -> Slave. |
| ☐ | **Phase 5: System Integration in Home Assistant** | | **Goal:** Make the system "smart". |
| ☐ | 5.1 Configure MODBUS integration in Home Assistant | | Create the sensors and entities for the slave node in `configuration.yaml` or via the UI. |
| ☐ | 5.2 Create dashboards and automations in HA | | Visualization of the states (valve, pump etc.) and creation of the actual irrigation logic. |
| ☐ | 5.3 Develop Python script for firmware update in HA | | Implementation of the chunk-based upload as a script that can be called from HA. |
| ☐ | **Phase 6: Setup and Commissioning** | | **Goal:** Install the finished system. |
| ☐ | 6.1 Build and test all required slave nodes | | Test each slave individually with the PC via USB adapter and configure the MODBUS address. |
| ☐ | 6.2 Final installation and cabling of the system | | Installation of the components in the shed, cabling of the RS485 bus. |
| ☐ | 6.3 Overall system test and calibration | | Calibrate level sensor, check valve running times, test fail-safe behavior. |