IOT Bridge noch nicht so richtig funktionsfähig. Odoo MQTT muss noch aufgeräumt werden

This commit is contained in:
Matthias Lotz 2026-02-07 19:44:47 +01:00
parent 8a414ed3ac
commit d0b7a5737d
7 changed files with 59 additions and 20 deletions

View File

@ -324,6 +324,16 @@ Die Bridge sollte einen Health-Check-Endpoint anbieten:
## Testing
### Manuelle Tests
```bash
# Shelly Simulator für Tests
python tests/tools/shelly_simulator.py --scenario session_end
python tests/tools/shelly_simulator.py --scenario full_session
python tests/tools/shelly_simulator.py --scenario timeout
python3 tests/tools/shelly_simulator.py --broker localhost --port 1883 --no-tls --username "" --password "" --scenario full_session
### Unit Tests
```bash

View File

@ -33,6 +33,14 @@ class LoggingConfig:
log_file: Optional[str] = None
@dataclass
class EventQueueConfig:
max_retries: int = 3
initial_retry_delay_s: float = 2.0
max_retry_delay_s: float = 60.0
retry_backoff_factor: float = 2.0
@dataclass
class SessionConfig:
strategy: str
@ -58,6 +66,7 @@ class BridgeConfig:
mqtt: MQTTConfig
odoo: OdooConfig
logging: LoggingConfig
event_queue: EventQueueConfig
devices: List[DeviceConfig]
@ -73,6 +82,7 @@ def load_config(config_path: str = "config.yaml") -> BridgeConfig:
mqtt_config = MQTTConfig(**data['mqtt'])
odoo_config = OdooConfig(**data.get('odoo', {}))
logging_config = LoggingConfig(**data.get('logging', {}))
event_queue_config = EventQueueConfig(**data.get('event_queue', {}))
devices = []
for dev_data in data.get('devices', []):
@ -90,5 +100,6 @@ def load_config(config_path: str = "config.yaml") -> BridgeConfig:
mqtt=mqtt_config,
odoo=odoo_config,
logging=logging_config,
event_queue=event_queue_config,
devices=devices
)

View File

@ -12,10 +12,12 @@ mqtt:
use_tls: true
odoo:
# URL for Odoo API (when not using mock)
# url: "http://localhost:8069"
# token: ""
use_mock: true
# Odoo REST API configuration for development
base_url: "http://odoo-dev:8069"
database: "OWS_MQTT"
username: "admin"
api_key: "" # Optional: Add API key for authentication
use_mock: false
logging:
level: "INFO" # DEBUG, INFO, WARNING, ERROR

View File

@ -13,10 +13,10 @@ mqtt:
odoo:
# Local Odoo instance from docker-compose
base_url: "http://odoo-dev:8069"
database: "your-db-name"
database: "OWS_MQTT"
username: "admin"
api_key: "" # Add your API key here when ready for Phase 2
use_mock: true # Set to false when testing real Odoo API
use_mock: false # Using real Odoo REST API
logging:
level: "DEBUG" # More verbose for development
@ -42,3 +42,16 @@ devices:
stop_debounce_s: 15
message_timeout_s: 20
heartbeat_interval_s: 300 # 5 minutes
- device_id: "testshelly-simulator"
mqtt_topic: "testshelly/status/pm1:0"
parser_type: "shelly_pm_mini_g3"
machine_name: "Test Shelly Simulator"
session_config:
strategy: "power_threshold"
standby_threshold_w: 20
working_threshold_w: 100
start_debounce_s: 3
stop_debounce_s: 15
message_timeout_s: 20
heartbeat_interval_s: 30 # 30 seconds for faster testing

View File

@ -41,17 +41,20 @@ def on_event_generated(event, logger, event_queue):
def on_mqtt_message(topic: str, payload: dict, logger, parser, device_id, detector):
"""Handle incoming MQTT messages."""
# Parse message
parsed = parser.parse_message(topic, payload)
if parsed and parsed.get('apower') is not None:
power_w = parsed['apower']
try:
# Parse message
parsed = parser.parse_message(topic, payload)
# Process in session detector
from datetime import datetime
detector.process_power_measurement(power_w, datetime.utcnow())
logger.debug(f"power_measurement device={device_id} power={power_w}W state={detector.state}")
if parsed and parsed.get('apower') is not None:
power_w = parsed['apower']
# Process in session detector
from datetime import datetime
detector.process_power_measurement(power_w, datetime.utcnow())
# logger.debug(f"power_measurement device={device_id} power={power_w}W state={detector.state}")
except Exception as e:
logger.error(f"on_mqtt_message_error error={str(e)}")
def main():

View File

@ -104,7 +104,7 @@ class MQTTClient:
self.message_callback(topic, payload_json)
except Exception as e:
logger.error(f"message_processing_error error={str(e)} topic={msg.topic}")
logger.error(f"message_processing_error error={str(e)} topic={topic}")
def connect(self) -> bool:
"""Connect to MQTT broker."""

View File

@ -29,7 +29,7 @@ class ShellyParser:
return None
except Exception as e:
logger.debug(f"parse_error", topic=topic, error=str(e))
logger.debug(f"parse_error topic={topic} error={str(e)}")
return None
def _parse_status_message(self, topic: str, data: dict) -> Optional[Dict]:
@ -63,11 +63,11 @@ class ShellyParser:
'temperature': data.get('temperature', {}).get('tC'),
}
logger.debug(f"parsed_status", device=device_id, apower=result['apower'])
logger.debug(f"parsed_status device={device_id} apower={result['apower']}")
return result
except Exception as e:
logger.error(f"status_parse_error", error=str(e))
logger.error(f"status_parse_error error={str(e)}")
return None
def _extract_device_id(self, topic: str) -> str: