Claude cleanup

This commit is contained in:
2026-08-26 10:38:56 +02:00
parent bd8925a278
commit 7aa7fe4693
8 changed files with 104 additions and 32 deletions

View File

@@ -1,4 +1,3 @@
from typing import overload
import librosa
from numba import jit
import numpy as np

View File

@@ -0,0 +1,51 @@
# Example config.yml for the MusicMouse python-backend.
#
# Reverse-engineered from main.py (load_config/Controller) since no schema
# was previously documented. Copy this file to config.yml in the directory
# passed as the CLI argument to main.py, e.g.:
#
# python main.py /media/musicmouse/
#
# main.py reads "<config_dir>/config.yml". Real credentials (hass_token,
# mqtt.password) should never be committed - keep the real config.yml
# outside the repo (e.g. only on the deployed device).
general:
# ALSA output device passed to python-vlc, e.g. "hw:0,0"; omit/null for VLC's default.
alsa_device: "softvol_effects"
# Serial port the ESP32 firmware is connected on.
serial_port: "/dev/ttyUSB0"
# Home Assistant connection used for light/service calls (hass_service()).
hass_url: "http://homeassistant.local:8123"
hass_token: "REPLACE_WITH_LONG_LIVED_ACCESS_TOKEN"
# MQTT broker used for the Home-Assistant-discoverable "shelf light".
mqtt:
server: "homeassistant.local"
user: "musicmouse"
password: "REPLACE_WITH_MQTT_PASSWORD"
# Optional playback/UI tuning (all have defaults if omitted).
min_volume: 0
max_volume: 32
volume_increment: 5 # per rotary-encoder tick
button_leds_brightness: 0.5 # 0..1, brightness of the prev/next button backlight
# One entry per figurine. The key is an arbitrary figure name (also used as
# the subdirectory name under the config dir when media_files is omitted).
figures:
fuchs:
# RFID tag id as a hex string (matched against bytes read from the reader).
id: "04a1b2c3d4"
# Exactly 4 colors: [primary, secondary, background, accent].
# Accepted formats: "#rrggbb" (RGB hex) or "wNN" (white channel hex, e.g. "wff").
colors: ["#ff6600", "#ffcc00", "#331100", "#ffffff"]
# Optional explicit list of media file paths for this figure's playlist.
# If omitted, main.py globs os.path.join(config_dir, "<figure_name>").
media_files: []
eule:
id: "04b2c3d4e5"
colors: ["#3355ff", "#66aaff", "#001133", "#ffffff"]

View File

@@ -23,7 +23,8 @@ if __name__ == "__main__":
url = sys.argv[1]
token = sys.argv[2]
loop = asyncio.get_event_loop()
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
hass = HomeAssistantClient(url, token)
async def hass_event(event, event_details):

View File

@@ -2,7 +2,9 @@ import asyncio
from enum import Enum
import struct
from led_cmds import *
from led_cmds import (EffectStaticConfig, EffectStaticDetailedConfig, EffectAlexaSwipeConfig,
EffectCircularConfig, EffectRandomTwoColorInterpolationConfig,
EffectSwipeAndChange, EffectReverseSwipe)
MAGIC_TOKEN_HOST_TO_FW = 0x1d6379e3
MAGIC_TOKEN_FW_TO_HOST = 0x10c65631

View File

@@ -26,12 +26,6 @@ class ColorRGBW:
assert 0<= other <= 1
return ColorRGBW(self.r * other, self.g * other, self.b * other, self.w * other)
def __eq__(self, other:'ColorRGBW'):
return self.r == other.r and self.g == other.g and self.b == other.b and self.w == other.w
def __neq__(self, other:'ColorRGBW'):
return not self == other
def without_white_channel(self, scale=1):
args = (min(1, e + self.w) for e in (self.r, self.g, self.b) )
return ColorRGBW(*args, 0)

View File

@@ -3,7 +3,7 @@
import asyncio
import sys
import serial_asyncio
from led_cmds import (ColorRGBW, ColorHSV, EffectCircularConfig, EffectStaticConfig,
from led_cmds import (ColorRGBW, EffectCircularConfig, EffectStaticConfig,
EffectRandomTwoColorInterpolationConfig, EffectAlexaSwipeConfig,
EffectSwipeAndChange, EffectReverseSwipe)
from host_driver import MusicMouseProtocol, RfidTokenRead, RotaryEncoderEvent, ButtonEvent, TouchButton, TouchButtonPress, TouchButtonRelease, mouse_leds_index_ranges
@@ -12,13 +12,10 @@ from glob import glob
from copy import deepcopy
import os
from hass_client import HomeAssistantClient
import argparse
from ruamel.yaml import YAML
import warnings
from pprint import pprint
from typing import Optional
from mqtt_json import start_mqtt
import aiohttp
yaml = YAML(typ='safe')
@@ -38,6 +35,7 @@ def parse_color(color_str: str):
def load_config(config_path):
# Schema documented in config.yml.example.
with open(os.path.join(config_path, "config.yml")) as cfg_file:
cfg = yaml.load(cfg_file)
for figure_name, figure_cfg in cfg["figures"].items():
@@ -205,12 +203,12 @@ class Controller:
eff_change = EffectRandomTwoColorInterpolationConfig()
eff_static = EffectStaticConfig(ColorRGBW(0, 0, 0, 0),
*mouse_leds_index_ranges[message.touch_button])
if self.audio_player.is_playing():
if figure and self.audio_player.is_playing():
primary_color, secondary_color, bg, accent = self.cfg["figures"][figure]["colors"]
eff_static.color = primary_color
self.protocol.mouse_led_effect(eff_static)
if self.audio_player.is_playing():
if figure and self.audio_player.is_playing():
primary_color, secondary_color, bg, accent = self.cfg["figures"][figure]["colors"]
eff_change.color1 = primary_color
eff_change.color2 = secondary_color
@@ -247,7 +245,8 @@ class Controller:
def main(config_path):
cfg = load_config(config_path)
loop = asyncio.get_event_loop()
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
hass = HomeAssistantClient(cfg["general"]["hass_url"], cfg["general"]["hass_token"], loop=loop)
coro = serial_asyncio.create_serial_connection(loop,

View File

@@ -2,7 +2,6 @@ from led_cmds import ColorRGBW, EffectStaticConfig, EffectStaticDetailedConfig,
import asyncio
import aiomqtt
import json
from copy import deepcopy
class ShelveLightMqtt:
@@ -155,21 +154,6 @@ class ShelveLightMqtt:
state_payload = json.dumps(self._state)
print("OUT ", state_payload)
await self._mqtt_client.publish(self._discovery_spec['state_topic'], state_payload.encode())
return
direct_ack = False
if direct_ack == True:
state_payload = json.dumps(state)
else:
s = deepcopy(self._state)
if s['state'] == "OFF":
state_payload = json.dumps({"state": "OFF"})
else:
s['color_mode'] = "rgbw"
state_payload = json.dumps(s)
print("OUT ", state_payload)
await self._mqtt_client.publish(self._discovery_spec['state_topic'], state_payload.encode())
async def start_mqtt(music_mouse_protocol, server, username, password):