Add auto-update for missing configuration settings
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 <noreply@anthropic.com>
This commit is contained in:
12
README.md
12
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:
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user