190 lines
7.6 KiB
Plaintext
190 lines
7.6 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": "output_dir is where finished ISOs land. It is gitignored — see .gitignore.",
|
|
"output_dir": "build-output"
|
|
}
|
|
}
|