112 lines
5.1 KiB
Python
112 lines
5.1 KiB
Python
"""Configuration schema for IoT Bridge using Pydantic."""
|
|
|
|
from pydantic import BaseModel, Field
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
|
|
class MQTTConfig(BaseModel):
|
|
"""MQTT Broker configuration."""
|
|
|
|
broker: str = Field(default="localhost", description="MQTT broker hostname")
|
|
port: int = Field(default=1883, ge=1, le=65535, description="MQTT broker port")
|
|
username: str | None = Field(default=None, description="MQTT username (optional)")
|
|
password: str | None = Field(default=None, description="MQTT password (optional)")
|
|
client_id: str = Field(default="iot_bridge", description="MQTT client ID")
|
|
keepalive: int = Field(default=60, ge=1, description="MQTT keepalive interval (s)")
|
|
use_tls: bool = Field(default=False, description="Use TLS/SSL for MQTT connection")
|
|
|
|
|
|
class OdooConfig(BaseModel):
|
|
"""Odoo connection configuration."""
|
|
|
|
base_url: str | None = Field(default=None, description="Odoo base URL")
|
|
database: str | None = Field(default=None, description="Odoo database name")
|
|
username: str | None = Field(default=None, description="Odoo username")
|
|
api_key: str | None = Field(default=None, description="Odoo API key")
|
|
use_mock: bool = Field(default=True, description="Use mock Odoo client for testing")
|
|
mock_failure_rate: float = Field(
|
|
default=0.0, ge=0.0, le=1.0, description="Mock failure rate for testing (0.0-1.0)"
|
|
)
|
|
|
|
|
|
class LoggingConfig(BaseModel):
|
|
"""Logging configuration."""
|
|
|
|
level: str = Field(default="INFO", description="Log level")
|
|
format: str = Field(default="json", description="Log format (json or console)")
|
|
log_file: str | None = Field(default=None, description="Log file path (optional)")
|
|
|
|
|
|
class EventQueueConfig(BaseModel):
|
|
"""Event queue retry configuration."""
|
|
|
|
max_retries: int = Field(default=3, ge=0, description="Maximum retry attempts")
|
|
initial_retry_delay_s: float = Field(default=2.0, gt=0, description="Initial retry delay (s)")
|
|
max_retry_delay_s: float = Field(default=60.0, gt=0, description="Maximum retry delay (s)")
|
|
retry_backoff_factor: float = Field(
|
|
default=2.0, gt=1.0, description="Exponential backoff factor"
|
|
)
|
|
|
|
|
|
class DeviceStatusConfig(BaseModel):
|
|
"""Configuration for device online/offline status monitoring."""
|
|
|
|
enabled: bool = Field(default=True, description="Enable device status monitoring")
|
|
timeout_s: int = Field(default=30, ge=1, description="Device offline timeout (s)")
|
|
check_interval_s: int = Field(default=5, ge=1, description="Status check interval (s)")
|
|
persistence_path: str = Field(
|
|
default="/data/device_status.json", description="Path to persist device status"
|
|
)
|
|
|
|
|
|
class SessionConfig(BaseModel):
|
|
"""Session detection configuration for a device."""
|
|
|
|
strategy: str = Field(default="power_threshold", description="Session detection strategy")
|
|
standby_threshold_w: float = Field(gt=0, description="Power threshold for session start (W)")
|
|
working_threshold_w: float = Field(gt=0, description="Power threshold for working state (W)")
|
|
start_debounce_s: float = Field(gt=0, description="Debounce time for session start (s)")
|
|
stop_debounce_s: float = Field(gt=0, description="Debounce time for session stop (s)")
|
|
message_timeout_s: float = Field(gt=0, description="Max time without messages (s)")
|
|
heartbeat_interval_s: float = Field(gt=0, description="Interval for heartbeat events (s)")
|
|
|
|
|
|
class DeviceConfig(BaseModel):
|
|
"""Configuration for a single IoT device."""
|
|
|
|
device_id: str = Field(min_length=1, description="Unique device identifier")
|
|
mqtt_topic: str = Field(min_length=1, description="MQTT topic to subscribe to")
|
|
parser_type: str = Field(default="shelly_pm", description="Parser type")
|
|
machine_name: str = Field(min_length=1, description="Human-readable machine name")
|
|
session_config: SessionConfig
|
|
|
|
|
|
class BridgeConfig(BaseModel):
|
|
"""Complete bridge configuration."""
|
|
|
|
mqtt: MQTTConfig
|
|
odoo: OdooConfig
|
|
logging: LoggingConfig
|
|
event_queue: EventQueueConfig
|
|
device_status: DeviceStatusConfig
|
|
devices: list[DeviceConfig]
|
|
|
|
|
|
class EnvOverrideSettings(BaseSettings):
|
|
"""Environment variable overrides for selected configuration values."""
|
|
|
|
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore")
|
|
|
|
mqtt_broker: str | None = Field(default=None, alias="MQTT_BROKER")
|
|
mqtt_port: int | None = Field(default=None, alias="MQTT_PORT")
|
|
mqtt_username: str | None = Field(default=None, alias="MQTT_USERNAME")
|
|
mqtt_password: str | None = Field(default=None, alias="MQTT_PASSWORD")
|
|
mqtt_client_id: str | None = Field(default=None, alias="MQTT_CLIENT_ID")
|
|
mqtt_keepalive: int | None = Field(default=None, alias="MQTT_KEEPALIVE")
|
|
mqtt_use_tls: bool | None = Field(default=None, alias="MQTT_USE_TLS")
|
|
|
|
odoo_base_url: str | None = Field(default=None, alias="ODOO_BASE_URL")
|
|
odoo_database: str | None = Field(default=None, alias="ODOO_DATABASE")
|
|
odoo_username: str | None = Field(default=None, alias="ODOO_USERNAME")
|
|
odoo_api_key: str | None = Field(default=None, alias="ODOO_API_KEY")
|