all repos — siam-py @ 59cb2e0050ff0485b9afae123547cec5d4a112a3

Unnamed repository; edit this file 'description' to name the repository.

Setup basic script
Tim Izzo tim@5ika.ch
Fri, 13 Nov 2026 14:49:39 +0100
commit

59cb2e0050ff0485b9afae123547cec5d4a112a3

2 files changed, 87 insertions(+), 0 deletions(-)

jump to
A main.py

@@ -0,0 +1,83 @@

+import io +import json +import subprocess +import wave +from datetime import date +from time import sleep + +import pyaudio +import requests +from playsound3 import playsound +from pysystemd import ServiceManager, ServiceStatus + +SIAM_DIR = "/home/sika/siam" +VOICE_PATH = SIAM_DIR + "/voices/ella.safetensors" +SESSION_ID = "ses_siam_" + date.today().isoformat() +AGENT = "siam-tts" + +services = ["ollama", "pocket-tts"] + + +def ensure_running_services(): + for service in services: + status = ServiceStatus(service) + if not status.is_running(): + print(service + " is not running") + manager = ServiceManager(service) + manager.start() + else: + print(service + " already running") + + +def sync_waybar(): + sleep(0.1) + subprocess.run(["pkill", "-RTMIN+8", "waybar"], check=True) + + +def get_hex_status(): + return json.loads( + subprocess.run( + ["hex", "status", "--json"], check=True, capture_output=True + ).stdout + )["capture"]["state"] + + +def tts(text): + response = requests.post("http://localhost:8000/tts", files={"text": (None, text)}) + response.raise_for_status() + + with wave.open(io.BytesIO(response.content), "rb") as wf: + p = pyaudio.PyAudio() + stream = p.open( + format=p.get_format_from_width(wf.getsampwidth()), + channels=wf.getnchannels(), + rate=wf.getframerate(), + output=True, + ) + stream.write(wf.readframes(wf.getnframes())) + stream.stop_stream() + stream.close() + p.terminate() + + +if get_hex_status() == "idle": + ensure_running_services() + playsound(SIAM_DIR + "/sounds/trigger/oui.wav") + subprocess.run(["hex", "dictation", "start"], check=True) + sync_waybar() +else: + stt_output = subprocess.run( + ["hex", "dictation", "stop", "--print"], check=True, capture_output=True + ).stdout.decode() + sync_waybar() + print("> " + stt_output) + + oc_output = subprocess.run( + "opencode run -s " + SESSION_ID + " --agent " + AGENT + ' "' + stt_output + '"', + shell=True, + check=True, + capture_output=True, + ).stdout.decode() + + print("< " + oc_output) + tts(oc_output)
A requirements.txt

@@ -0,0 +1,4 @@

+playsound3==3.3.2 +pysystemd==1.1 +requests==2.34.2 +pyaudio==0.2.14