diff --git a/software/esphome/irrigation_system.yaml b/software/esphome/irrigation_system.yaml index 571513b..ede0593 100644 --- a/software/esphome/irrigation_system.yaml +++ b/software/esphome/irrigation_system.yaml @@ -1,3 +1,11 @@ +# =================================================================== +# ESPHome Configuration - Final Version +# +# This version corrects the C++ function call inside the valve actions +# to use the correct `send` method from the ModbusDevice base class, +# which is compatible with the esp-idf framework. +# =================================================================== + esphome: name: irrigation-system friendly_name: Bewässerung @@ -5,7 +13,7 @@ esphome: esp32: board: esp32-c6-devkitm-1 framework: - type: esp-idf + type: esp-idf # Set to esp-idf as required by the ESP32-C6 board wifi: ssid: !secret wifi_ssid @@ -24,88 +32,135 @@ logger: web_server: -# UART-Bus für Modbus +# =================================================================== +# HARDWARE SETUP - COMPLETE +# =================================================================== + +# --- UART for RS485 Communication --- uart: id: uart_bus tx_pin: GPIO1 rx_pin: GPIO2 baud_rate: 9600 + data_bits: 8 stop_bits: 1 parity: NONE -# Modbus-Komponente (der Hub) +# --- Base Modbus component for the bus --- modbus: - - id: modbus1 + - id: modbus_hub uart_id: uart_bus +# --- Modbus Controller for the specific valve device --- modbus_controller: - - id: valve_device - address: 0x01 - modbus_id: modbus1 + - id: valve_controller + modbus_id: modbus_hub + address: 0 # The Modbus address of your valve. Change if not 0. + # update_interval: 1s -number: +# =================================================================== +# SENSORS - COMPLETE +# =================================================================== +sensor: + # This sensor reads the raw 16-bit value from the valve's input register. - platform: modbus_controller - modbus_controller_id: valve_device - id: valve_controller_command - name: "Valve Control" - address: 0x01 - value_type: U_WORD - # min_value: 0 - # max_value: 2 - # step: 1 + modbus_controller_id: valve_controller + name: "Valve Raw Status" + id: valve_raw_status + internal: true # Hide from Home Assistant UI + register_type: read # 'read' is the valid type for input registers + address: 0x0000 # The address of the register to read + value_type: U_WORD # Read the full 16-bit unsigned word + - platform: modbus_controller + modbus_controller_id: valve_controller + name: "VDD" + id: valve_vdd + register_type: read # 'read' is the valid type for input registers + address: 0x00FC # The address of the register to read + value_type: U_WORD # Read the full 16-bit unsigned word + entity_category: diagnostic # Mark as diagnostic + unit_of_measurement: "V" + accuracy_decimals: 2 # Show two decimal places + # Apply filters to convert the raw value to volts and update periodically + filters: + - lambda: |- + // Convert the raw VDD value to volts + return x / 1000.0; // Assuming the value is in millivolts + - heartbeat: 60s # Update every 60 seconds + - delta: 200 # Only update if the value changes by more than 200 mV -globals: - - id: my_valve_is_open - type: bool - restore_value: false - initial_value: 'true' +# =================================================================== +# TEXT SENSORS FOR HUMAN-READABLE STATUS +# =================================================================== +text_sensor: + # 1. This text sensor extracts the HIGH BYTE for the operation status. + - platform: template + name: "Valve Operation" + id: valve_operation_status + icon: "mdi:state-machine" + lambda: |- + // Extract the high byte from the raw status sensor + // using a bitwise right shift. + int operation_code = (int)id(valve_raw_status).state >> 8; + switch (operation_code) { + case 0: return {"Idle"}; + case 1: return {"Opening"}; + case 2: return {"Closing"}; + case 3: return {"Obstacle Detected"}; + case 4: return {"End Position Not Reached"}; + default: return {"Unknown Operation"}; + } + # 2. This text sensor extracts the LOW BYTE for the current valve state. + - platform: template + name: "Valve Position" + id: valve_position_status + icon: "mdi:valve" + lambda: |- + // Extract the low byte from the raw status sensor + // using a bitwise AND mask. + int state_code = (int)id(valve_raw_status).state & 0xFF; + switch (state_code) { + case 0: return {"Closed"}; + case 1: return {"Open"}; + default: return {"Unknown"}; + } + +# =================================================================== +# THE MAIN VALVE COMPONENT +# =================================================================== valve: - platform: template - name: "Modbus Ventil" - id: my_modbus_valve - - # Lambda, um den aktuellen Zustand zu bestimmen - # Liest den Zustand aus der globalen Variable + name: "Modbus Controlled Valve" + id: modbus_valve + optimistic: false + # The lambda determines the current state (open or closed) of the valve. lambda: |- - return id(my_valve_is_open); - - # Aktion beim Drücken auf "Öffnen" + int state_code = (int)id(valve_raw_status).state & 0xFF; + if (state_code == 1) { + return true; // Open + } else if (state_code == 0) { + return false; // Closed + } else { + return {}; // Unknown + } + # Action to execute when the "OPEN" button is pressed. open_action: - - number.set: - id: valve_controller_command - value: 1 - - globals.set: - id: my_valve_is_open - value: 'true' - - # Aktion beim Drücken auf "Schliessen" + - lambda: |- + // Use the send() command inherited from ModbusDevice + // Function 0x06: Write Single Register + // Payload for value 1 is {0x00, 0x01} + const uint8_t data[] = {0x00, 0x01}; + id(valve_controller).send(0x06, 0x0000, 1, 2, data); + # Action to execute when the "CLOSE" button is pressed. close_action: - - number.set: - id: valve_controller_command - value: 2 - - globals.set: - id: my_valve_is_open - value: 'false' - - # (Optional) Aktion beim Drücken auf "Stopp" + - lambda: |- + // Payload for value 2 is {0x00, 0x02} + const uint8_t data[] = {0x00, 0x02}; + id(valve_controller).send(0x06, 0x0000, 1, 2, data); + # Action to execute when the "STOP" button is pressed. stop_action: - - number.set: - id: valve_controller_command - value: 0 - -sensor: -- platform: modbus_controller - modbus_controller_id: valve_device - name: "Supply Voltage" - register_type: read - device_class: voltage - entity_category: diagnostic - accuracy_decimals: 2 - filters: - - lambda: |- - return x / 1000.0; - address: 0x00F5 - unit_of_measurement: "V" - value_type: U_WORD - + - lambda: |- + // Payload for value 3 is {0x00, 0x03} + const uint8_t data[] = {0x00, 0x03}; + id(valve_controller).send(0x06, 0x0000, 1, 2, data);