Regenbasierte automatische Gartenbewässerung + homeMesh-Anbindung für AutoAction-Regeleditor

- Neues stündliches Python-Script (restricted/gartenbewaesserung/auto_watering.py): holt Niederschlags-
  und Sonnenuntergangsdaten von Open-Meteo, wertet je Zone (Hochbeete/Tröge/Garten vorn) individuelle
  Regen-Schwellenwerte und Mindest-Bewässerungsdauern aus und startet bei Bedarf per MQTT den passenden
  Automatik-Modus der Ventilsteuerung im Zeitraum vor Sonnenuntergang; veröffentlicht den Regen-Status
  zusätzlich stündlich als retained MQTT-Nachricht je Zone.
- Web-UI: neue Bewässerungs-Steuerung/-Anzeige (ajax/watering.php, js/solar/solarMQTT.js,
  assets/img/realtime.svg) inkl. Live-Status-Icons (aus/geplant/pausiert/aktiv per Farbe und Symbol).
- AutoAction-Regeleditor (ajax/actorDetails.php, sensorDetails.php, fillActorDD.php, fillSensorDD.php,
  tahoma.php, AutoAction.php) liest Actor-/Sensor-Parameter jetzt live aus der homeMesh-Datenbank statt
  aus stark vereinfachten Altfeldern, inkl. zugehöriger Anpassungen am Device-Discovery-Tooling
  (restricted/deviceDiscovery/*, neues logic_module.py).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-26 20:19:27 +02:00
co-authored by Claude Sonnet 5
parent 4de95c1a29
commit 29f752eafe
22 changed files with 1693 additions and 234 deletions
@@ -106,7 +106,7 @@ class WLEDDiscovery:
return wled_devices
@staticmethod
def is_wled_device(ip: str, timeout: float = 1.0) -> bool:
def is_wled_device(ip: str, timeout: float = 2.0) -> bool:
"""Prüft ob IP ein WLED-Gerät ist"""
try:
response = requests.get(
@@ -190,16 +190,16 @@ class WLEDAPI:
eff_values = self.get_effects()
commands = [
{'command': 'on', 'parameters': []},
{'command': 'off', 'parameters': []},
{'command': 'An', 'url': '{"on":true}', 'parameters': []},
{'command': 'Aus', 'url': '{"on":false}', 'parameters': []},
{
'command': 'setBrightness',
'command': 'Helligkeit', 'url': '{"bri":%brightness%}',
'parameters': [
{'name': 'brightness', 'type': 'integer', 'min': 0, 'max': 255}
]
},
{
'command': 'setColor',
'command': 'Farbe', 'url': '{"seg":[{"col":[[%red%,%green%,%blue%]]}]}',
'parameters': [
{'name': 'red', 'type': 'integer', 'min': 0, 'max': 255},
{'name': 'green', 'type': 'integer', 'min': 0, 'max': 255},
@@ -207,13 +207,13 @@ class WLEDAPI:
]
},
{
'command': 'setEffect',
'command': 'Effekt', 'url': '{"seg":[{"fx":%effect%}]}',
'parameters': [
{'name': 'effect', 'type': 'integer', 'min': 0, 'max': 255, 'values': eff_values}
]
},
{
'command': 'setPreset',
'command': 'Preset', 'url': '{"ps":%preset%}',
'parameters': [
{'name': 'preset', 'type': 'integer', 'min': 1, 'max': 250, 'values': preset_values}
]
@@ -223,12 +223,14 @@ class WLEDAPI:
states = []
if state:
states.append({
'name': 'power',
'name': 'An',
'url': 'on',
'type': 'boolean',
'current_value': state.get('on', False)
})
states.append({
'name': 'brightness',
'name': 'Helligkeit',
'url': 'bri',
'type': 'integer',
'current_value': state.get('bri', 0)
})
@@ -238,7 +240,8 @@ class WLEDAPI:
colors = segments[0].get('col', [[0,0,0]])
if colors and len(colors) > 0:
states.append({
'name': 'color_rgb',
'name': 'Farbe',
'url': 'seg[0].col[0]',
'type': 'array',
'current_value': colors[0]
})