""" Configuration module for MIDI-to-Hue application. Handles loading, creating and validating configuration. """ import os import json from typing import Dict, Any, Optional # Default config file path DEFAULT_CONFIG_FILE = 'midi_hue_config.json' # Default MIDI-to-Hue mapping if no config file exists DEFAULT_CONFIG = { "midi_device": 1, # Index of MIDI device to use (from available inputs list) "update_interval_ms": 50, # Throttling interval in milliseconds "bridge_ip": "192.168.178.35", # Default Bridge IP "mappings": [ { "midi_channel": 5, "midi_control": 1, "light_name": "Zimmer Decke", "parameter": "bri", "value_transform": "value * 2" # MIDI range 0-127 to Hue brightness 0-254 }, { "midi_channel": 6, "midi_control": 1, "light_name": "Fernseher links", "parameter": "bri", "value_transform": "value * 2" # MIDI range 0-127 to Hue brightness 0-254 }, ] } class ConfigManager: """Manages configuration loading, validation and access.""" def __init__(self, config_file: str = DEFAULT_CONFIG_FILE): """Initialize the config manager with a specific config file.""" self.config_file = config_file self.config = self._load_or_create_config() def _load_or_create_config(self) -> Dict[str, Any]: """Load config from file or create with defaults if it doesn't exist.""" try: if os.path.exists(self.config_file): with open(self.config_file, 'r') as f: config = json.load(f) print(f"Loaded configuration from {self.config_file}") return config except Exception as e: print(f"Error loading config file: {e}") # If we get here, either the file doesn't exist or there was an error # Create the default config file with open(self.config_file, 'w') as f: json.dump(DEFAULT_CONFIG, f, indent=4) print(f"Created default configuration file at {self.config_file}") return DEFAULT_CONFIG def get(self, key: str, default: Any = None) -> Any: """Get a configuration value by key with a default fallback.""" return self.config.get(key, default) def get_mappings(self) -> list: """Get all mappings from the configuration.""" return self.config.get("mappings", []) def get_bridge_ip(self) -> str: """Get the Bridge IP address.""" return self.config.get("bridge_ip", "192.168.178.35") def get_update_interval_sec(self) -> float: """Get the update interval in seconds.""" update_interval_ms = self.config.get("update_interval_ms", 50) return update_interval_ms / 1000 # Convert to seconds def get_midi_device_index(self) -> int: """Get the MIDI device index.""" return self.config.get("midi_device", 1)