Files
mc-webui/app/config.py
MarekWo 97323649c7 feat(tcp): document TCP connection in .env.example + fix defaults
- Add MC_TCP_HOST and MC_TCP_PORT options to .env.example with clear
  documentation for serial vs TCP transport selection
- Change default MC_TCP_PORT from 5000 to 5555 (avoids Flask conflict)
- Wire MC_TCP_HOST/MC_TCP_PORT through docker-compose.yml from .env
  (previously was commented-out hardcoded values)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 07:27:08 +01:00

120 lines
3.9 KiB
Python

"""
Configuration module - loads settings from environment variables
"""
import os
import logging
from pathlib import Path
from typing import Optional
logger = logging.getLogger(__name__)
class Config:
"""Application configuration from environment variables"""
# MeshCore device configuration
MC_SERIAL_PORT = os.getenv('MC_SERIAL_PORT', '/dev/ttyUSB0')
MC_DEVICE_NAME = os.getenv('MC_DEVICE_NAME', 'MeshCore')
MC_CONFIG_DIR = os.getenv('MC_CONFIG_DIR', '/root/.config/meshcore')
# MC_BRIDGE_URL removed in v2 (direct device communication)
# Archive configuration (v1 — archives move to SQLite in v2)
MC_ARCHIVE_DIR = os.getenv('MC_ARCHIVE_DIR', '/root/.archive/meshcore')
MC_ARCHIVE_ENABLED = os.getenv('MC_ARCHIVE_ENABLED', 'true').lower() == 'true'
MC_ARCHIVE_RETENTION_DAYS = int(os.getenv('MC_ARCHIVE_RETENTION_DAYS', '7'))
# v2: Database
MC_DB_PATH = os.getenv('MC_DB_PATH', '') # empty = auto: {MC_CONFIG_DIR}/mc-webui.db
# v2: TCP connection (alternative to serial, e.g. meshcore-proxy)
MC_TCP_HOST = os.getenv('MC_TCP_HOST', '') # empty = use serial
MC_TCP_PORT = int(os.getenv('MC_TCP_PORT', '5555'))
# v2: Backup
MC_BACKUP_ENABLED = os.getenv('MC_BACKUP_ENABLED', 'true').lower() == 'true'
MC_BACKUP_HOUR = int(os.getenv('MC_BACKUP_HOUR', '2'))
MC_BACKUP_RETENTION_DAYS = int(os.getenv('MC_BACKUP_RETENTION_DAYS', '7'))
# v2: Connection
MC_AUTO_RECONNECT = os.getenv('MC_AUTO_RECONNECT', 'true').lower() == 'true'
MC_LOG_LEVEL = os.getenv('MC_LOG_LEVEL', 'INFO')
# Flask server configuration
FLASK_HOST = os.getenv('FLASK_HOST', '0.0.0.0')
FLASK_PORT = int(os.getenv('FLASK_PORT', '5000'))
FLASK_DEBUG = os.getenv('FLASK_DEBUG', 'false').lower() == 'true'
# Derived paths
@property
def msgs_file_path(self) -> Path:
"""Get the full path to the .msgs file"""
return Path(self.MC_CONFIG_DIR) / f"{self.MC_DEVICE_NAME}.msgs"
@property
def archive_dir_path(self) -> Path:
"""Get the full path to archive directory"""
return Path(self.MC_ARCHIVE_DIR)
@property
def db_path(self) -> Path:
"""Get SQLite database path"""
if self.MC_DB_PATH:
return Path(self.MC_DB_PATH)
return Path(self.MC_CONFIG_DIR) / 'mc-webui.db'
@property
def use_tcp(self) -> bool:
"""True if TCP transport should be used instead of serial"""
return bool(self.MC_TCP_HOST)
def __repr__(self):
transport = f"tcp={self.MC_TCP_HOST}:{self.MC_TCP_PORT}" if self.use_tcp else f"serial={self.MC_SERIAL_PORT}"
return (
f"Config(device={self.MC_DEVICE_NAME}, "
f"{transport}, "
f"config_dir={self.MC_CONFIG_DIR})"
)
# Global config instance
config = Config()
class RuntimeConfig:
"""
Runtime configuration that can be updated after startup.
Used for values that are detected/fetched at runtime, like
device name from bridge auto-detection.
"""
_device_name: Optional[str] = None
_device_name_source: str = "config"
@classmethod
def set_device_name(cls, name: str, source: str = "detected"):
"""Set the runtime device name"""
cls._device_name = name
cls._device_name_source = source
logger.info(f"Runtime device name set: {name} (source: {source})")
@classmethod
def get_device_name(cls) -> str:
"""Get device name - prefers runtime value, falls back to config"""
return cls._device_name or config.MC_DEVICE_NAME
@classmethod
def get_device_name_source(cls) -> str:
"""Get the source of the device name (detected/config/fallback)"""
return cls._device_name_source
@classmethod
def get_msgs_file_path(cls) -> Path:
"""Get the full path to the .msgs file using runtime device name"""
return Path(config.MC_CONFIG_DIR) / f"{cls.get_device_name()}.msgs"
# Global runtime config instance
runtime_config = RuntimeConfig()