From 1b1a40b094f40738272476c88122cfc4c06d0085 Mon Sep 17 00:00:00 2001 From: grabowski Date: Mon, 27 Oct 2025 16:02:50 +0700 Subject: [PATCH] Add auto-update for missing configuration settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implemented automatic config file updates to add missing settings with default values on startup. This eliminates manual config editing when upgrading to newer versions. Features: - Auto-updates config.json with missing settings - Auto-updates user_config.json with missing user preferences - Console logging shows which settings were added - Preserves existing values - only adds missing keys - Writes updated config back to file automatically - Graceful error handling if write fails System config (config.json): - Comprehensive defaults for all sections - GPIO, audio, paths, backup, web, system settings - New settings like volume_greeting, volume_button, volume_beep User config (user_config.json): - Loop-based checking against default_config - Automatic save when updates are detected - Error logging for troubleshooting Benefits: - Seamless upgrades without manual config edits - No breaking changes when new features are added - Users see exactly what was added in console - Backward compatible with old config files Example console output: [CONFIG] Added missing setting: system.volume_beep = 70 [CONFIG] Updated config.json with missing defaults [USER_CONFIG] Added missing setting: volume_button = 70 [USER_CONFIG] Updated user_config.json with missing defaults Updated README.md to document auto-update feature. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- README.md | 12 +++++ rotary_phone_web.py | 110 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 104 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 291d98b..84b4d61 100644 --- a/README.md +++ b/README.md @@ -491,6 +491,18 @@ rotary_phone_data/ # Default location (configurable) All configuration is done via the `config.json` file. **No need to edit Python code!** +### Auto-Update Feature + +The system automatically adds missing configuration settings with default values when it starts: + +- **config.json** - System configuration is auto-updated with any missing settings +- **user_config.json** - User settings are auto-updated with new defaults +- Console shows which settings were added: `[CONFIG] Added missing setting: system.volume_beep = 70` +- Original config is preserved - only missing keys are added +- No manual editing required when upgrading to newer versions + +This means you can upgrade the code and your old config files will work automatically! + ### Configuration File Structure The `config.json` file contains all system settings: diff --git a/rotary_phone_web.py b/rotary_phone_web.py index 0d65d39..fe36e26 100644 --- a/rotary_phone_web.py +++ b/rotary_phone_web.py @@ -24,7 +24,7 @@ import io # Load configuration def load_system_config(): - """Load system configuration from config.json""" + """Load system configuration from config.json and auto-update with missing defaults""" config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config.json') # Check if config exists, otherwise use example @@ -39,7 +39,77 @@ def load_system_config(): sys.exit(1) with open(config_path, 'r') as f: - return json.load(f) + config = json.load(f) + + # Default values for all settings + defaults = { + 'gpio': { + 'hook_pin': 17, + 'hook_pressed_state': 'LOW', + 'extra_button_enabled': False, + 'extra_button_pin': 27, + 'extra_button_pressed_state': 'LOW' + }, + 'audio': { + 'device_index': 1, + 'chunk_size': 1024, + 'format': 'paInt16', + 'channels': 1, + 'sample_rate': 48000, + 'max_record_seconds': 300 + }, + 'paths': { + 'base_dir': './rotary_phone_data', + 'recordings_dir': 'recordings', + 'sounds_dir': 'sounds' + }, + 'backup': { + 'enabled': True, + 'usb_paths': ['/media/usb0', '/media/usb1'], + 'verify_crc': True, + 'backup_on_write': True + }, + 'web': { + 'port': 8080, + 'max_upload_size_mb': 50 + }, + 'system': { + 'active_greeting': 'dialtone.wav', + 'extra_button_sound': 'button_sound.wav', + 'beep_sound': 'beep.wav', + 'beep_enabled': True, + 'greeting_delay_seconds': 0, + 'volume': 70, + 'volume_greeting': 70, + 'volume_button': 70, + 'volume_beep': 70 + } + } + + # Check if any defaults are missing and add them + updated = False + for section, section_defaults in defaults.items(): + if section not in config: + config[section] = section_defaults + updated = True + print(f"[CONFIG] Added missing section: {section}") + else: + for key, default_value in section_defaults.items(): + if key not in config[section]: + config[section][key] = default_value + updated = True + print(f"[CONFIG] Added missing setting: {section}.{key} = {default_value}") + + # Save updated config if changes were made + if updated: + try: + with open(config_path, 'w') as f: + json.dump(config, f, indent=2) + print(f"[CONFIG] Updated config.json with missing defaults") + except Exception as e: + print(f"[CONFIG] Warning: Could not save updated config: {e}") + + return config # Load system configuration SYS_CONFIG = load_system_config() @@ -274,23 +344,27 @@ class RotaryPhone: try: with open(USER_CONFIG_FILE, 'r') as f: config = json.load(f) - # Ensure required keys exist - if "volume" not in config: - config["volume"] = SYS_CONFIG['system']['volume'] - if "volume_greeting" not in config: - config["volume_greeting"] = SYS_CONFIG['system'].get('volume_greeting', 70) - if "volume_button" not in config: - config["volume_button"] = SYS_CONFIG['system'].get('volume_button', 70) - if "volume_beep" not in config: - config["volume_beep"] = SYS_CONFIG['system'].get('volume_beep', 70) - if "greeting_delay" not in config: - config["greeting_delay"] = SYS_CONFIG['system'].get('greeting_delay_seconds', 0) - if "beep_enabled" not in config: - config["beep_enabled"] = SYS_CONFIG['system'].get('beep_enabled', True) - if "beep_sound" not in config: - config["beep_sound"] = SYS_CONFIG['system'].get('beep_sound', 'beep.wav') + + # Check for missing keys and add defaults + updated = False + for key, default_value in default_config.items(): + if key not in config: + config[key] = default_value + updated = True + print(f"[USER_CONFIG] Added missing setting: {key} = {default_value}") + + # Save updated config if changes were made + if updated: + try: + with open(USER_CONFIG_FILE, 'w') as fw: + json.dump(config, fw, indent=2) + print(f"[USER_CONFIG] Updated user_config.json with missing defaults") + except Exception as e: + print(f"[USER_CONFIG] Warning: Could not save updated config: {e}") + return config - except: + except Exception as e: + print(f"[USER_CONFIG] Error loading user config: {e}, using defaults") pass return default_config