SmartestHome/CoreSystemConfig.json.template

191 lines
8.0 KiB
Plaintext

{
"_README": [
"SmartestHome — the single source of truth for every build script in tools/.",
"",
"Copy this to CoreSystemConfig.json (that filename is gitignored), fill it in, then",
"run any builder in tools/. Nothing in tools/ has its own copy of an IP, a port, a",
"token or a URL — every build script reads this file, so a value can only ever be",
"wrong in one place instead of six.",
"",
"ANYTHING DERIVABLE IS DERIVED, NEVER TYPED. You give the subnet prefix once and one",
"last octet per host; the builders compute every address and every service URL from",
"those. That is what makes the container-host and llm-host ISOs a TWINNED pair: the",
"container host learns the LLM host's address because it was computed from the same",
"two numbers, not because someone typed it into two files and kept them in sync.",
"",
"THIS FILE WILL CONTAIN SECRETS once filled in (Wi-Fi PSK, service tokens, MQTT and",
"HA credentials) and those secrets get burnt into the ISOs the builders produce.",
"Treat both this file and the built ISOs as credentials: .gitignore covers them, but",
"an ISO on a USB stick in a drawer is still every token in this household.",
"",
"Run 'tools/validate-config.py' at any time to check it. Every builder runs it first",
"and refuses to build on an error."
],
"household": {
"_comment": "Baked into every image. timezone must be a real zoneinfo name; keyboard_layout an xkb layout ('localectl list-x11-keymap-layouts').",
"timezone": "Europe/Vienna",
"locale": "en_US.UTF-8",
"keyboard_layout": "de",
"debian_release": "bookworm"
},
"network": {
"_comment": "subnet_prefix is the first three octets of the smart-home VLAN, no trailing dot. Every host below places itself in it by last octet, which is also how the validator guarantees they can actually reach each other.",
"subnet_prefix": "192.168.30",
"netmask": "255.255.255.0",
"gateway_last_octet": 1,
"dns_servers": ["192.168.30.1"],
"wifi": {
"_comment": "Used by kiosk images that have no wired connection. Leave ssid empty if every device is wired; the validator will then not complain about an empty psk.",
"ssid": "",
"psk": ""
}
},
"container_host": {
"_comment": "The Phase 1 machine: Home Assistant, Mosquitto, Zigbee2MQTT, Frigate, Grocy and this repo's own services. Everything else in the household points at this address.",
"hostname": "smarthome-core",
"ip_last_octet": 12,
"install_disk": "/dev/sda",
"admin_username": "amir",
"enable": {
"_comment": "Mirrors setup-container-host.sh's ENABLE_* flags. Turning one off here also stops the builders from demanding the tokens it would have needed.",
"identity": true,
"pantry_vision": true,
"digest_engine": false,
"admin_canvas": false,
"trash_calendar": false,
"transit": false,
"trip_planning": false,
"chores": true,
"ntfy": true,
"node_red": true,
"netdata": true,
"homepage": true,
"portainer": true,
"mealie": false,
"gallery_smb": false,
"music_assistant": false,
"backups": false
}
},
"llm_host": {
"_comment": "The Phase 3 Ollama machine. Its address is what the container host's OLLAMA_HOST is derived from — change ip_last_octet here and every consumer follows automatically.",
"hostname": "smarthome-llm",
"ip_last_octet": 13,
"install_disk": "/dev/sda",
"admin_username": "amir",
"tier": "auto",
"text_model_gpu": "qwen2.5:14b-instruct",
"text_model_cpu": "qwen2.5:7b-instruct",
"vision_model": "llava",
"pull_vision_model": true,
"keep_alive": "30m",
"max_loaded_models": 1,
"num_parallel": 1
},
"ports": {
"_comment": "The whole published-port inventory, matching docs/network-integration.md §4. The validator FAILS on any duplicate here, which is the mechanism that keeps a collision from reaching a deployment. NOTE music_assistant: its own default is 8095, which collides with pantry_vision — and because it runs network_mode:host, Compose's own port-conflict check never fires (project-plan open decision #31). 8101 is set here to resolve that, but you must also configure Music Assistant itself to listen on it; this file cannot make it move.",
"home_assistant": 8123,
"mqtt": 1883,
"zigbee2mqtt": 8080,
"node_red": 1880,
"homepage": 3000,
"ntfy": 8090,
"portainer": 9000,
"gallery_smb": 445,
"mealie": 9925,
"frigate": 5000,
"grocy": 9283,
"digest_web": 8091,
"admin_web": 8094,
"pantry_vision": 8095,
"pantry_web": 8096,
"identity": 8097,
"identity_web": 8098,
"transit": 8099,
"otp": 8100,
"music_assistant": 8101,
"ollama": 11434
},
"secrets": {
"_comment": "Generate the tokens with: openssl rand -hex 32. Each is required only if the service that uses it is enabled above; the validator says which. ha_token is a Long-Lived Access Token from HA's own UI (profile -> Security) and cannot be generated ahead of time — leave it empty for the first build and re-run once HA is up.",
"identity_token": "",
"pantry_vision_token": "",
"transit_token": "",
"mqtt_username": "",
"mqtt_password": "",
"ha_token": "",
"ssh_authorized_key": "",
"kiosk_password": "",
"admin_password_hash": ""
},
"voice": {
"_comment": "Defaults for any kiosk with voice_satellite enabled; a kiosk may override wake_word individually.",
"wake_word": "ok_nabu"
},
"kiosks": [
{
"_comment": "type must be one of: thin-client, touch-panel, door-panel, kitchen-display. hostname must be unique and a valid DNS label — it is what the HA device shows up as.",
"type": "door-panel",
"hostname": "door-panel",
"friendly_name": "Door panel",
"kiosk_username": "kiosk",
"voice_satellite": true,
"enable_installer": false
},
{
"type": "kitchen-display",
"hostname": "kitchen-display",
"friendly_name": "Kitchen fridge display",
"kiosk_username": "kiosk",
"voice_satellite": false,
"enable_installer": false
},
{
"type": "thin-client",
"hostname": "thin-client-living",
"friendly_name": "Living room thin client",
"kiosk_username": "kiosk",
"voice_satellite": false,
"enable_installer": false,
"enable_steam_link": true,
"enable_gesture_control": false
},
{
"type": "touch-panel",
"hostname": "touch-panel-kitchen",
"friendly_name": "Kitchen touch panel",
"kiosk_username": "kiosk",
"voice_satellite": false,
"enable_installer": false
}
],
"audio_endpoints": [
{
"_comment": "Headless Spotify Connect appliances for rooms with no thin client. arch picks the toolchain — and they are genuinely different toolchains producing different artifacts, not one image for both: 'amd64' is a mini PC + USB DAC built with live-build (an .iso), 'arm64' is a Raspberry Pi + HiFiBerry Amp2 built with rpi-image-gen (an .img). build-all.sh builds every entry here, so listing both architectures gets you both. hostname doubles as the Spotify Connect device name and must be unique across kiosks too — they're all devices on one network.",
"hostname": "audio-endpoint-livingroom",
"friendly_name": "Living room",
"arch": "amd64"
},
{
"hostname": "audio-endpoint-kitchen",
"friendly_name": "Kitchen",
"arch": "arm64"
}
],
"build": {
"_comment": "Where finished images land, relative to the repo root. Gitignored — see .gitignore — because these carry every secret in this file. arm64_prebake bakes each arm64 audio endpoint's hostname into its own image, so every device in the household is named by the build rather than typed into Raspberry Pi Imager afterwards; it costs one full rpi-image-gen run per room. Set it false to build a single generic .img and name each unit at flash time instead.",
"output_dir": "iso-out",
"arm64_prebake": true
}
}