implement random add;

implement setting of i2c cmds on startup
This commit is contained in:
2025-11-17 15:04:19 +01:00
parent f356c13b98
commit 25fa781c80

View File

@@ -7,6 +7,7 @@ import logging as log
import json
from datetime import datetime
import asyncio
import random
from dotenv import load_dotenv
from fastapi import FastAPI, HTTPException
@@ -36,7 +37,6 @@ os.environ["PULSE_LATENCY_MSEC"] = "3"
SETTINGS_CACHE1: dict = {}
SETTINGS_CACHE2: dict = {}
def get_device_index_by_name(name: str):
"""Return the device index for a given device name, or None if not found.
@@ -114,6 +114,8 @@ def save_settings(persisted: dict, secondary: bool = False) -> None:
else:
save_stream_settings(persisted)
def gen_random_add() -> str:
return ':'.join(['%02X' % random.randint(0, 255) for _ in range(6)])
app = FastAPI()
@@ -135,6 +137,26 @@ multicaster2: multicast_control.Multicaster | None = None
_stream_lock = asyncio.Lock() # serialize initialize/stop_audio on API side
async def _init_i2c_on_startup() -> None:
cmds = [
["i2cset", "-f", "-y", "1", "0x4a", "0x00", "0x00"],
["i2cset", "-f", "-y", "1", "0x4a", "0x06", "0x10"],
["i2cset", "-f", "-y", "1", "0x4a", "0x07", "0x10"],
]
for cmd in cmds:
try:
proc = await asyncio.create_subprocess_exec(
*cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await proc.communicate()
if proc.returncode != 0:
log.warning("i2cset failed (%s): rc=%s stderr=%s", " ".join(cmd), proc.returncode, (stderr or b"").decode(errors="ignore").strip())
except Exception as e:
log.warning("Exception running i2cset (%s): %s", " ".join(cmd), e, exc_info=True)
async def _stop_all() -> bool:
global multicaster1, multicaster2
was_running = False
@@ -208,14 +230,15 @@ async def initialize(conf: auracast_config.AuracastConfigGroup):
if isinstance(big.audio_source, str) and big.audio_source.startswith('device:'):
big.audio_source = f'device:{device_index}'
devinfo = sd.query_devices(device_index)
capture_rate = 48000
max_in = int(devinfo.get('max_input_channels') or 1)
channels = max(1, min(2, max_in))
for big in conf.bigs:
big.input_format = f"int16le,{capture_rate},{channels}"
big.input_format = f"int16le,{48000},{channels}"
if getattr(conf, 'qos_config', None) and getattr(conf.qos_config, 'number_of_retransmissions', None) is not None:
conf.qos_config.max_transport_latency_ms = int(conf.qos_config.number_of_retransmissions) * 10 + 3
conf.qos_config.max_transport_latency_ms = int(conf.qos_config.number_of_retransmissions) * 10 + 3
for big in conf.bigs:
big.random_address = gen_random_add()
multicaster1 = multicast_control.Multicaster(conf, conf.bigs)
await multicaster1.init_broadcast()
@@ -272,6 +295,8 @@ async def initialize2(conf: auracast_config.AuracastConfigGroup):
isinstance(big.audio_source, str) and big.audio_source.startswith('device:')
for big in conf.bigs
)
conf.qos_config.max_transport_latency_ms = int(conf.qos_config.number_of_retransmissions) * 10 + 3
for big in conf.bigs:
if isinstance(big.audio_source, str) and big.audio_source.startswith('device:'):
device_name = big.audio_source.split(':', 1)[1]
@@ -280,10 +305,8 @@ async def initialize2(conf: auracast_config.AuracastConfigGroup):
device_index = resolve_input_device_index(device_name)
if device_index is None:
raise HTTPException(status_code=400, detail=f"Audio device '{device_name}' not found.")
big.audio_source = f'device:{device_index}'
if getattr(conf, 'qos_config', None) and getattr(conf.qos_config, 'number_of_retransmissions', None) is not None:
conf.qos_config.max_transport_latency_ms = int(conf.qos_config.number_of_retransmissions) * 10 + 3
big.audio_source = f'device:{device_index}'
multicaster2 = multicast_control.Multicaster(conf, conf.bigs)
await multicaster2.init_broadcast()
if any(isinstance(big.audio_source, str) and (big.audio_source.startswith("device:") or big.audio_source.startswith("file:")) for big in conf.bigs):
@@ -482,6 +505,7 @@ async def _startup_autostart_event():
log.info("Refreshing PipeWire device cache.")
# Hydrate settings cache once to avoid disk I/O during /status
_init_settings_cache_from_disk()
await _init_i2c_on_startup()
refresh_pw_cache()
asyncio.create_task(_autostart_from_settings())