System Configuration - xante8088/kasa-monitor GitHub Wiki
System Configuration
Complete guide for configuring and customizing Kasa Monitor system settings.
Configuration Overview
┌─────────────────────────────────────┐
│ Configuration Hierarchy │
├─────────────────────────────────────┤
│ 1. Environment Variables │
│ 2. Configuration Files │
│ 3. Database Settings │
│ 4. Runtime Configuration │
│ 5. User Preferences │
└─────────────────────────────────────┘
Quick Configuration
Essential Settings
# .env file
NODE_ENV=production
TZ=America/New_York
POLLING_INTERVAL=60
DATA_RETENTION_DAYS=365
LOG_LEVEL=info
Docker Environment
# docker-compose.yml
environment:
- NODE_ENV=production
- TZ=America/New_York
- POLLING_INTERVAL=60
- DATABASE_PATH=/app/data/kasa_monitor.db
- LOG_LEVEL=info
Environment Variables
Core Settings
| Variable | Description | Default | Options |
|---|---|---|---|
NODE_ENV |
Application environment | development | development, production, test |
TZ |
System timezone | UTC | Any valid timezone |
LOG_LEVEL |
Logging verbosity | info | debug, info, warn, error |
PORT |
Frontend port | 3000 | Any available port |
API_PORT |
Backend API port | 5272 | Any available port |
Database Configuration
# SQLite
SQLITE_PATH=/app/data/kasa_monitor.db
DATABASE_BACKUP_ENABLED=true
DATABASE_BACKUP_SCHEDULE="0 2 * * *"
DATABASE_BACKUP_RETENTION_DAYS=30
# InfluxDB (Optional - Use environment variables)
INFLUXDB_ENABLED=false
INFLUXDB_URL=http://influxdb:8086
DOCKER_INFLUXDB_INIT_USERNAME=admin
DOCKER_INFLUXDB_INIT_PASSWORD=$(openssl rand -base64 24)
DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=$(openssl rand -hex 32)
DOCKER_INFLUXDB_INIT_ORG=kasa-monitor
DOCKER_INFLUXDB_INIT_BUCKET=device-data
INFLUXDB_RETENTION_DAYS=90
Security Settings
# Authentication (CRITICAL - Generate secure values)
JWT_SECRET_KEY=$(openssl rand -base64 32) # Required for production
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
REFRESH_TOKEN_EXPIRE_DAYS=7
# Session
SESSION_SECRET=$(openssl rand -base64 32)
SESSION_TIMEOUT_MINUTES=30
SESSION_COOKIE_SECURE=true
SESSION_COOKIE_HTTPONLY=true
# CORS (Comma-separated list, no wildcards in production)
CORS_ALLOWED_ORIGINS=https://yourdomain.com,https://app.yourdomain.com
ENVIRONMENT=production # Enforces strict CORS checking
ALLOWED_METHODS=GET,POST,PUT,DELETE
ALLOWED_HEADERS=Content-Type,Authorization
# File Upload Security
MAX_UPLOAD_SIZE_MB=10
ALLOWED_UPLOAD_EXTENSIONS=.zip,.py,.json,.pem,.crt,.key
REQUIRE_PLUGIN_SIGNATURES=true
UPLOAD_QUARANTINE_DIR=/app/quarantine
Performance Settings
# Polling
POLLING_INTERVAL=60 # Seconds
POLLING_THREADS=4
POLLING_BATCH_SIZE=10
POLLING_TIMEOUT=10
# Caching
CACHE_ENABLED=true
CACHE_TTL=300 # Seconds
REDIS_URL=redis://redis:6379
REDIS_PASSWORD=
# Data Management
DATA_RETENTION_DAYS=365
DATA_AGGREGATION_ENABLED=true
DATA_COMPRESSION_ENABLED=true
Network Configuration
# Device Discovery
DISCOVERY_ENABLED=true
DISCOVERY_BROADCAST_ADDRESS=255.255.255.255
DISCOVERY_PORT=9999
DISCOVERY_TIMEOUT=5
DISCOVERY_INTERVAL=3600
# Network Ranges
ALLOWED_SUBNETS=192.168.1.0/24,10.0.0.0/8
BLOCKED_IPS=
Configuration Files
Main Configuration
config/production.yml:
app:
name: Kasa Monitor
version: 1.0.0
environment: production
debug: false
server:
host: 0.0.0.0
port: 5272
workers: 4
timeout: 30
database:
type: sqlite
path: /app/data/kasa_monitor.db
pool_size: 5
max_overflow: 10
pool_timeout: 30
influxdb:
enabled: false
url: http://influxdb:8086
token: ${INFLUXDB_TOKEN}
org: kasa-monitor
bucket: device-data
redis:
enabled: true
url: redis://redis:6379
password:
db: 0
decode_responses: true
logging:
level: INFO
format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
file: /app/logs/kasa-monitor.log
max_bytes: 10485760 # 10MB
backup_count: 5
security:
jwt_secret: ${JWT_SECRET_KEY}
algorithm: HS256
access_token_expire: 30 # minutes
refresh_token_expire: 7 # days
password_min_length: 12
password_require_special: true
monitoring:
metrics_enabled: true
metrics_port: 9090
health_check_interval: 30
alerting_enabled: true
features:
auto_discovery: true
energy_monitoring: true
cost_calculation: true
scheduling: true
notifications: true
api_enabled: true
Device Configuration
config/devices.yml:
defaults:
polling_interval: 60
timeout: 10
retry_count: 3
retry_delay: 5
device_types:
HS110:
has_energy_meter: true
max_power: 1800
calibration_factor: 1.0
HS100:
has_energy_meter: false
max_power: 1800
KP115:
has_energy_meter: true
max_power: 1800
calibration_factor: 1.0
groups:
Living Room:
polling_interval: 30
alert_threshold: 100
Bedroom:
polling_interval: 120
alert_threshold: 50
calibration:
voltage_correction: 1.0
current_correction: 1.0
power_factor_correction: 1.0
Rate Configuration
config/electricity_rates.yml:
default_rate:
type: simple
currency: USD
rate_per_kwh: 0.12
time_of_use:
enabled: false
rates:
peak:
rate: 0.15
hours: "14:00-20:00"
days: ["mon", "tue", "wed", "thu", "fri"]
off_peak:
rate: 0.08
hours: "20:00-14:00"
weekend:
rate: 0.10
days: ["sat", "sun"]
tiered_rates:
enabled: false
tiers:
- limit: 500
rate: 0.10
- limit: 1000
rate: 0.12
- limit: null
rate: 0.15
seasonal_rates:
enabled: false
seasons:
summer:
months: [6, 7, 8]
rate: 0.14
winter:
months: [12, 1, 2]
rate: 0.11
standard:
rate: 0.12
Database Settings
System Configuration Table
-- View current settings
SELECT * FROM system_config;
-- Update setting
UPDATE system_config
SET value = '30'
WHERE key = 'polling_interval';
-- Add new setting
INSERT INTO system_config (key, value, type, description)
VALUES ('custom_setting', 'value', 'string', 'Description');
Common Settings
-- Core settings
INSERT OR REPLACE INTO system_config VALUES
('polling_interval', '60', 'integer', 'Device polling interval in seconds'),
('data_retention_days', '365', 'integer', 'Days to retain detailed data'),
('summary_retention_days', '1825', 'integer', 'Days to retain summary data'),
('timezone', 'America/New_York', 'string', 'System timezone'),
('date_format', 'YYYY-MM-DD', 'string', 'Date display format'),
('time_format', 'HH:mm:ss', 'string', 'Time display format'),
('currency', 'USD', 'string', 'Currency for cost calculations'),
('theme', 'auto', 'string', 'UI theme (light/dark/auto)');
-- Feature flags
INSERT OR REPLACE INTO system_config VALUES
('auto_discovery_enabled', 'true', 'boolean', 'Enable automatic device discovery'),
('energy_monitoring_enabled', 'true', 'boolean', 'Enable energy monitoring'),
('cost_calculation_enabled', 'true', 'boolean', 'Enable cost calculations'),
('scheduling_enabled', 'true', 'boolean', 'Enable device scheduling'),
('notifications_enabled', 'true', 'boolean', 'Enable notifications'),
('api_enabled', 'true', 'boolean', 'Enable API access');
-- Performance settings
INSERT OR REPLACE INTO system_config VALUES
('max_concurrent_polls', '10', 'integer', 'Maximum concurrent device polls'),
('poll_timeout', '10', 'integer', 'Device poll timeout in seconds'),
('cache_ttl', '300', 'integer', 'Cache time-to-live in seconds'),
('batch_size', '100', 'integer', 'Batch processing size');
Runtime Configuration
Dynamic Settings
# Get runtime config
@app.get("/api/config")
async def get_config():
config = {
"polling_interval": int(os.getenv("POLLING_INTERVAL", 60)),
"timezone": os.getenv("TZ", "UTC"),
"features": {
"discovery": os.getenv("DISCOVERY_ENABLED", "true") == "true",
"scheduling": os.getenv("SCHEDULING_ENABLED", "true") == "true"
}
}
return config
# Update runtime config
@app.post("/api/config")
async def update_config(settings: dict):
for key, value in settings.items():
db.execute(
"UPDATE system_config SET value = ? WHERE key = ?",
(value, key)
)
# Reload configuration
reload_config()
Feature Toggles
FEATURE_FLAGS = {
"energy_monitoring": True,
"cost_calculation": True,
"scheduling": True,
"notifications": True,
"advanced_analytics": False,
"cloud_sync": False
}
def is_feature_enabled(feature: str) -> bool:
return FEATURE_FLAGS.get(feature, False)
# Usage
if is_feature_enabled("scheduling"):
schedule_device_tasks()
User Preferences
User-Specific Settings
{
"theme": "dark",
"language": "en",
"timezone": "America/New_York",
"date_format": "MM/DD/YYYY",
"time_format": "12h",
"notifications": {
"email": true,
"push": false,
"sms": false
},
"dashboard": {
"refresh_interval": 30,
"default_view": "grid",
"show_costs": true,
"show_graphs": true
},
"devices": {
"sort_by": "name",
"group_by": "location",
"show_offline": true
}
}
Preference API
# Get user preferences
@app.get("/api/users/me/preferences")
async def get_preferences(user: User = Depends(get_current_user)):
return json.loads(user.settings or "{}")
# Update preferences
@app.patch("/api/users/me/preferences")
async def update_preferences(
preferences: dict,
user: User = Depends(get_current_user)
):
db.execute(
"UPDATE users SET settings = ? WHERE id = ?",
(json.dumps(preferences), user.id)
)
Configuration Management
Backup Configuration
#!/bin/bash
# backup-config.sh
BACKUP_DIR="/backups/config"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
# Backup all config files
tar czf $BACKUP_DIR/config-$TIMESTAMP.tar.gz \
/app/config/*.yml \
/app/.env \
/app/data/system_config.sql
# Export database settings
sqlite3 /app/data/kasa_monitor.db \
"SELECT * FROM system_config" > $BACKUP_DIR/settings-$TIMESTAMP.csv
Restore Configuration
#!/bin/bash
# restore-config.sh
BACKUP_FILE=$1
# Extract config files
tar xzf $BACKUP_FILE -C /
# Restart application
docker-compose restart
Configuration Validation
import yaml
import jsonschema
def validate_config(config_file):
with open(config_file, 'r') as f:
config = yaml.safe_load(f)
schema = {
"type": "object",
"required": ["app", "server", "database"],
"properties": {
"app": {
"type": "object",
"required": ["name", "version", "environment"]
},
"server": {
"type": "object",
"required": ["host", "port"]
}
}
}
jsonschema.validate(config, schema)
return True
Advanced Configuration
Custom Modules
# config/custom_modules.py
CUSTOM_MODULES = {
"authentication": "custom_auth.CustomAuthProvider",
"discovery": "custom_discovery.CustomDiscovery",
"notifications": "custom_notify.CustomNotifier"
}
# Load custom module
def load_custom_module(module_type):
module_path = CUSTOM_MODULES.get(module_type)
if module_path:
module_name, class_name = module_path.rsplit('.', 1)
module = importlib.import_module(module_name)
return getattr(module, class_name)()
Plugin System
# config/plugins.yml
plugins:
- name: weather_integration
enabled: true
config:
api_key: ${WEATHER_API_KEY}
update_interval: 3600
- name: smart_scheduling
enabled: false
config:
ml_model: /models/scheduling.pkl
- name: voice_control
enabled: false
config:
provider: alexa
Environment-Specific Overrides
# Load environment-specific config
def load_config():
env = os.getenv('NODE_ENV', 'development')
# Base config
with open('config/base.yml', 'r') as f:
config = yaml.safe_load(f)
# Environment override
env_file = f'config/{env}.yml'
if os.path.exists(env_file):
with open(env_file, 'r') as f:
env_config = yaml.safe_load(f)
config = merge_configs(config, env_config)
return config
Configuration Examples
High-Performance Setup
# High device count configuration
server:
workers: 8
thread_pool: 16
database:
pool_size: 20
max_overflow: 40
polling:
interval: 30
threads: 8
batch_size: 50
cache:
enabled: true
ttl: 600
size: 1000
Energy-Saving Setup
# Low-power configuration
polling:
interval: 300 # 5 minutes
threads: 2
features:
auto_discovery: false
real_time_updates: false
database:
pool_size: 2
compression: true
Development Setup
# Development configuration
app:
debug: true
reload: true
logging:
level: DEBUG
console: true
security:
cors_enabled: true
allowed_origins: "*"
Troubleshooting
Configuration Issues
Config not loading:
# Check file permissions
ls -la /app/config/
# Validate YAML syntax
python -c "import yaml; yaml.safe_load(open('/app/config/production.yml'))"
# Check environment variables
docker exec kasa-monitor env | grep -E "NODE_ENV|TZ|LOG_LEVEL"
Settings not applying:
# Restart application
docker-compose restart
# Clear cache
docker exec kasa-monitor redis-cli FLUSHALL
# Check database
docker exec kasa-monitor sqlite3 /app/data/kasa_monitor.db \
"SELECT * FROM system_config WHERE key='polling_interval'"
Best Practices
- Use Environment Variables for sensitive data
- Version Control configuration files
- Validate configurations before applying
- Document custom settings
- Test configuration changes in staging
- Backup before major changes
- Monitor after configuration updates
Related Pages
- Installation - Initial configuration
- Docker Deployment - Container configuration
- Security Guide - Security settings
- Performance Tuning - Performance configuration
- Backup & Recovery - Configuration backup
Document Version: 1.1.0
Last Updated: 2025-08-20
Review Status: Current
Change Summary: Updated security settings with JWT secret management, CORS configuration, file upload security, and InfluxDB credential security