feat(esphome): Add initial irrigation system configuration

This commit introduces the initial ESPHome configuration for the irrigation system.

- `irrigation_system.yaml`: ESPHome configuration with Modbus valve control.

- `create_secrets.py`: Script to generate `secrets.yaml`.

- `secrets.yaml.example`: Example secrets file.

- `requirements.txt`: Python dependencies.

- `.gitignore`: Standard ESPHome gitignore file.
Signed-off-by: Eduard Iten <eduard@iten.pro>
This commit is contained in:
Eduard Iten 2025-07-14 11:32:25 +02:00
parent e1ae96506d
commit 6f304efb57
5 changed files with 177 additions and 0 deletions

5
software/esphome/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
# Gitignore settings for ESPHome
# This is an example and may include too much for your use-case.
# You can modify this file to suit your needs.
/.esphome/
/secrets.yaml

View File

@ -0,0 +1,55 @@
#!/usr/bin/env python3
import secrets
import string
import os
import base64
from ruamel.yaml import YAML
def generate_password(length=32):
"""Generate a random password."""
alphabet = string.ascii_letters + string.digits
return ''.join(secrets.choice(alphabet) for i in range(length))
def generate_api_key():
"""Generate a random 32-byte key and base64 encode it."""
return base64.b64encode(secrets.token_bytes(32)).decode('utf-8')
SECRETS_FILE = 'secrets.yaml'
# In a real ESPHome project, secrets are often included from a central location
# but for this script, we'll assume it's in the current directory.
# You might need to adjust this path.
secrets_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), SECRETS_FILE)
yaml = YAML()
yaml.preserve_quotes = True
# To prevent line wrapping
yaml.width = 4096
try:
with open(secrets_path, 'r') as f:
secrets_data = yaml.load(f)
if secrets_data is None:
secrets_data = {}
except FileNotFoundError:
print(f"Info: '{SECRETS_FILE}' not found. A new file will be created.")
secrets_data = {}
# Generate new random passwords
new_api_key = generate_api_key()
new_ota_password = generate_password()
# Update the dictionary with the new passwords
if 'api_password' in secrets_data:
del secrets_data['api_password']
secrets_data['api_key'] = new_api_key
secrets_data['ota_password'] = new_ota_password
# Write the updated dictionary back to the YAML file
with open(secrets_path, 'w') as f:
yaml.dump(secrets_data, f)
print(f"Successfully updated '{SECRETS_FILE}'.")
print("New values:")
print(f" api_key: {new_api_key}")
print(f" ota_password: {new_ota_password}")

View File

@ -0,0 +1,111 @@
esphome:
name: irrigation-system
friendly_name: Bewässerung
esp32:
board: esp32-c6-devkitm-1
framework:
type: esp-idf
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
fast_connect: true
api:
encryption:
key: !secret api_key
ota:
platform: esphome
password: !secret ota_password
logger:
web_server:
# UART-Bus für Modbus
uart:
id: uart_bus
tx_pin: GPIO1
rx_pin: GPIO2
baud_rate: 9600
stop_bits: 1
parity: NONE
# Modbus-Komponente (der Hub)
modbus:
- id: modbus1
uart_id: uart_bus
modbus_controller:
- id: valve_device
address: 0x01
modbus_id: modbus1
number:
- 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
globals:
- id: my_valve_is_open
type: bool
restore_value: false
initial_value: 'true'
valve:
- platform: template
name: "Modbus Ventil"
id: my_modbus_valve
# Lambda, um den aktuellen Zustand zu bestimmen
# Liest den Zustand aus der globalen Variable
lambda: |-
return id(my_valve_is_open);
# Aktion beim Drücken auf "Öffnen"
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"
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"
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

View File

@ -0,0 +1,2 @@
ruamel.yaml
esphome

View File

@ -0,0 +1,4 @@
wifi_ssid: 'PUT YOUR WIFI SSID HERE'
wifi_password: 'PUT YOUR WIFI PASSWORD HERE'
api_key: 'PUT YOUR KEY HERE OR USE create_secrets.py'
ota_password: 'PUT YOUR KEY HERE OR USE create_secrets.py'