- 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>
96 lines
3.1 KiB
Python
96 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Base Module Interface
|
|
Definiert die einheitliche Schnittstelle für alle Gerätemodule
|
|
"""
|
|
|
|
from abc import ABC, abstractmethod
|
|
from typing import List, Dict, Tuple
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class BaseModule(ABC):
|
|
"""
|
|
Abstrakte Basisklasse für alle Gerätemodule
|
|
|
|
Jedes Modul muss nur discover() implementieren und gibt
|
|
eine Liste von (actors, sensors) zurück.
|
|
Die Datenbank-Logik bleibt im Hauptscript.
|
|
"""
|
|
|
|
def __init__(self, config):
|
|
"""
|
|
Initialisiert das Modul
|
|
|
|
Args:
|
|
config: Config-Objekt mit allen Einstellungen
|
|
"""
|
|
self.config = config
|
|
self.module_name = self.__class__.__name__.replace('Module', '')
|
|
|
|
@abstractmethod
|
|
def discover(self) -> Tuple[List[Dict], List[Dict]]:
|
|
"""
|
|
Führt Device Discovery durch
|
|
|
|
Returns:
|
|
Tuple (actors, sensors) mit Listen von Dicts:
|
|
|
|
Actor Dict Format:
|
|
{
|
|
'type': str, # z.B. 'RollerShutter'
|
|
'name': str, # z.B. 'Wohnzimmer Rollo'
|
|
'url': str, # Eindeutige ID/URL
|
|
'commands': [ # Liste von Commands
|
|
{
|
|
'command': str,
|
|
'parameters': [
|
|
{
|
|
'name': str,
|
|
'type': str,
|
|
'min': float (optional),
|
|
'max': float (optional),
|
|
'url': str, # Eindeutige ID/URL
|
|
'values': list (optional)
|
|
}
|
|
]
|
|
}
|
|
],
|
|
'states': [ # Liste von States
|
|
{
|
|
'name': str,
|
|
'type': int/str,
|
|
'current_value': any,
|
|
'unit': str (optional)
|
|
}
|
|
]
|
|
}
|
|
|
|
Sensor Dict Format:
|
|
{
|
|
'type': str, # z.B. 'TemperatureSensor'
|
|
'name': str, # z.B. 'Außentemperatur'
|
|
'url': str, # Eindeutige ID/URL
|
|
'states': [ # Liste von States
|
|
{
|
|
'name': str,
|
|
'type': int/str,
|
|
'current_value': any,
|
|
'url': str, # Eindeutige ID/URL
|
|
'unit': str (optional)
|
|
}
|
|
]
|
|
}
|
|
"""
|
|
pass
|
|
|
|
def is_enabled(self) -> bool:
|
|
"""Prüft ob Modul aktiviert ist"""
|
|
return True # Override in Subklassen falls nötig
|
|
|
|
def get_name(self) -> str:
|
|
"""Gibt Modulname zurück"""
|
|
return self.module_name
|