Files
heos/config.py
T
franzz 7c19ff9096
Deploy HEOS panel / deploy (push) Successful in 25s
Add spotify integration
2026-09-15 22:07:43 +02:00

106 lines
4.4 KiB
Python

"""Everything you might want to change lives here.
Copy the values out of `GET /api/targets` (or the old `/targets`) the
first time you run this, so the names below match exactly what HEOS
reports for your own devices.
"""
import os
from pathlib import Path
def _load_dotenv(path: Path):
"""A `source .env` a shell might forget to `export` is a whole class of
bug this sidesteps: read the file directly, rather than trusting
whatever the calling shell's environment happens to contain. Existing
environment variables still win, so a real export (or systemd's
EnvironmentFile) overrides the file rather than the other way round."""
if not path.exists():
return
for line in path.read_text().splitlines():
line = line.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, _, value = line.partition("=")
os.environ.setdefault(key.strip(), value.strip())
_load_dotenv(Path(__file__).resolve().parent / ".env")
# --- Network ----------------------------------------------------------
# Any ONE HEOS device's IP is enough: HEOS is a distributed system, so
# whichever unit you connect to can see and control every player and
# group on the network.
HEOS_HOST = "192.168.0.10"
HEOS_PORT = 1255
# Port the panel itself listens on.
WEB_PORT = 5443
# --- Rooms ------------------------------------------------------------
# key -> how to find it on the network, and how to label it in the UI.
#
# heos_name : the EXACT name HEOS reports for that player or group.
# players : only for a target that is a HEOS *group* (a stereo pair
# or an In-Room Group). List its member players, leader
# first. Leave it out and the panel learns the members the
# first time it sees the group un-merged, then remembers
# them in members.json -- which is what lets it rebuild the
# pair after you unmerge it from the AVR.
# spotify_name : only needed if a room's Spotify Connect name differs
# from heos_name -- GET /api/spotify/devices?account=fifou shows what
# Spotify actually calls it. Defaults to heos_name.
TARGETS = {
"avr": {
"label": "Home Cinema",
"heos_name": "Home Cinema", # AVR-X3800H
},
"home400": {
"label": "Lego Room",
"heos_name": "Lego Room", # Denon Home 400
},
"living_room_group": {
"label": "Living Room",
"heos_name": "Denon Home 200 L", # 2x Denon Home 200, In-Room Group
"spotify_name": "Living Room", # what Spotify Connect calls the pair
# "players": ["Denon Home 200 L", "Denon Home 200 R"],
},
}
# The AVR is always the group host: its content takes over every room
# that joins, which is the whole point of the merge buttons.
HOST_KEY = "avr"
# The rooms that get a card with volume + a join/leave button, in order.
ROOM_KEYS = ["home400", "living_room_group"]
# --- Behaviour --------------------------------------------------------
# The grid the volume buttons snap to. A tap moves to the next multiple of
# this rather than adding it, so at 5 a level of 23 goes to 25, not 28.
VOLUME_STEP = 5
# Narrows the AVR's input picker to the sources you actually use, by their
# HEOS input id (see GET /api/avr/inputs for the exact strings, e.g.
# "inputs/aux_in_1"), and sets their order in the list. Empty = every
# source HEOS reports for it.
AVR_INPUT_CODES = []
# Shown as the app's name on the iOS home screen.
APP_NAME = "Heos"
# --- Spotify (optional) -------------------------------------------------
# One Spotify button per account on each speaker's card (not the AVR's),
# resuming that account's playback there -- see the README's Spotify section and
# tools/spotify_auth.py. Credentials come from .env, never from here, so
# they stay out of git. One developer app serves every account; only the
# refresh token differs, since that is what each account's login produces.
SPOTIFY_CLIENT_ID = os.environ.get("SPOTIFY_CLIENT_ID")
SPOTIFY_CLIENT_SECRET = os.environ.get("SPOTIFY_CLIENT_SECRET")
# key -> button label and that account's refresh token, in button order.
# An account without a token gets no button.
SPOTIFY_ACCOUNTS = {
"fifou": {"label": "Fifou", "refresh_token": os.environ.get("SPOTIFY_FIFOU_REFRESH_TOKEN")},
"clarita": {"label": "Clarita", "refresh_token": os.environ.get("SPOTIFY_CLARITA_REFRESH_TOKEN")},
}