Changes on device

This commit is contained in:
Martin Bauer 2021-12-26 11:30:56 +01:00
parent da9373e74d
commit 59060d6636
5 changed files with 100 additions and 40 deletions

View File

@ -60,10 +60,10 @@ class RfidTokenRead:
class RotaryEncoderEvent: class RotaryEncoderEvent:
def __init__(self, msg_content: bytes): def __init__(self, msg_content: bytes):
self.position, self.direction = struct.unpack("<iB", msg_content) self.position, self.increment, self.direction = struct.unpack("<iiB", msg_content)
def __repr__(self): def __repr__(self):
return f"Rotary event: pos {self.position}, dir {self.direction}" return f"Rotary event: pos {self.position}, incr {self.increment}, dir {self.direction}"
class TouchButtonPress: class TouchButtonPress:

View File

@ -6,7 +6,7 @@ import serial_asyncio
from led_cmds import (ColorRGBW, ColorHSV, EffectStaticConfig, from led_cmds import (ColorRGBW, ColorHSV, EffectStaticConfig,
EffectRandomTwoColorInterpolationConfig, EffectAlexaSwipeConfig, EffectRandomTwoColorInterpolationConfig, EffectAlexaSwipeConfig,
EffectSwipeAndChange, EffectReverseSwipe) EffectSwipeAndChange, EffectReverseSwipe)
from host_driver import MusicMouseProtocol, RfidTokenRead, RotaryEncoderEvent, ButtonEvent, TouchButton, TouchButtonPress, TouchButtonRelease from host_driver import MusicMouseProtocol, RfidTokenRead, RotaryEncoderEvent, ButtonEvent, TouchButton, TouchButtonPress, TouchButtonRelease, mouse_leds_index_ranges
from player import AudioPlayer from player import AudioPlayer
from glob import glob from glob import glob
from copy import deepcopy from copy import deepcopy
@ -44,6 +44,10 @@ def load_config(config_path):
return cfg return cfg
def hass_service(hass, domain, service, **kwargs):
asyncio.create_task(hass.call_service(domain, service, kwargs))
class MusicMouseState: class MusicMouseState:
def __init__(self, protocol: MusicMouseProtocol): def __init__(self, protocol: MusicMouseProtocol):
self.current_figure: str = None self.current_figure: str = None
@ -80,11 +84,17 @@ class MusicMouseState:
class Controller: class Controller:
def __init__(self, protocol, cfg): def __init__(self, protocol, hass, cfg):
self.cfg = cfg self.cfg = cfg
self.audio_player = AudioPlayer(cfg["general"]["alsa_device"]) self.audio_player = AudioPlayer(cfg["general"]["alsa_device"])
self.audio_player.set_volume(50)
self.mmstate = MusicMouseState(protocol) self.mmstate = MusicMouseState(protocol)
self.protocol = protocol
self.hass = hass
vol_min = self.cfg["general"].get("min_volume", None)
vol_max = self.cfg["general"].get("max_volume", None)
self.audio_player.set_volume_limits(vol_min, vol_max)
protocol.register_message_callback(self.on_firmware_msg) protocol.register_message_callback(self.on_firmware_msg)
self.audio_player.on_playlist_end_callback = self._run_off_animation self.audio_player.on_playlist_end_callback = self._run_off_animation
@ -105,7 +115,7 @@ class Controller:
self.mmstate.figure_removed() self.mmstate.figure_removed()
elif tagid in self._rfid_to_figure_name: elif tagid in self._rfid_to_figure_name:
figure = self._rfid_to_figure_name[tagid] figure = self._rfid_to_figure_name[tagid]
primary_color, secondary_color, *rest = self.cfg["figures"]["colors"] primary_color, secondary_color, *rest = self.cfg["figures"][figure]["colors"]
self._start_animation(primary_color, secondary_color) self._start_animation(primary_color, secondary_color)
self.mmstate.button_leds(self.cfg["general"].get("button_leds_brightness", 0.5)) self.mmstate.button_leds(self.cfg["general"].get("button_leds_brightness", 0.5))
@ -125,7 +135,8 @@ class Controller:
if isinstance(message, RfidTokenRead): if isinstance(message, RfidTokenRead):
self.handle_rfid_event(message.id) self.handle_rfid_event(message.id)
elif isinstance(message, RotaryEncoderEvent): elif isinstance(message, RotaryEncoderEvent):
volume_increment = self.cfg["general"].get("volume_increment", 2) volume_increment = self.cfg["general"].get("volume_increment", 2) * abs(
message.increment)
if message.direction == 2: if message.direction == 2:
self.audio_player.change_volume(volume_increment) self.audio_player.change_volume(volume_increment)
elif message.direction == 1: elif message.direction == 1:
@ -135,35 +146,59 @@ class Controller:
self.audio_player.previous() self.audio_player.previous()
elif message.button == "right" and message.event == "pressed": elif message.button == "right" and message.event == "pressed":
self.audio_player.next() self.audio_player.next()
elif False and isinstance(message, TouchButtonPress): elif message.button == "rotary" and message.event == "pressed":
if current_figure: hass_service(self.hass, "light", "toggle", entity_id="light.kinderzimmer_fluter")
ccfg = color_cfg[current_figure] elif isinstance(message, TouchButtonPress):
protocol.mouse_led_effect( figure = self.mmstate.current_figure
EffectStaticConfig(ccfg.accent, *mouse_leds[message.touch_button])) if figure and self.audio_player.is_playing():
#if message.touch_button == TouchButton.RIGHT_FOOT: primary_color, secondary_color, bg, accent = self.cfg["figures"][figure]["colors"]
# asyncio.create_task( self.protocol.mouse_led_effect(
# hass.call_service("switch", "toggle", {"entity_id": "switch.tasmota06"})) EffectStaticConfig(accent, *mouse_leds_index_ranges[message.touch_button]))
# asyncio.create_task(
# hass.call_service("light", "turn_on", {"entity_id": "light.arbeitszimmer_fluter"}))
#elif message.touch_button == TouchButton.LEFT_FOOT:
# asyncio.create_task(
# hass.call_service("light", "turn_off", {"entity_id": "light.arbeitszimmer_fluter"}))
elif False and isinstance(message, TouchButtonRelease): colors = {
if current_figure: TouchButton.RIGHT_FOOT: {
ccfg = color_cfg[current_figure] 'rgb_color': [235, 255, 67]
},
TouchButton.LEFT_FOOT: {
'color_temp': 469
},
TouchButton.RIGHT_EAR: {
'rgb_color': [101, 49, 255]
},
TouchButton.LEFT_EAR: {
'rgb_color': [255, 74, 254]
},
}
hass_service(self.hass,
"light",
"turn_on",
entity_id="light.kinderzimmer_fluter",
**colors[message.touch_button])
#if message.touch_button == TouchButton.RIGHT_FOOT:
# asyncio.create_task(
# self.hass.call_service("switch", "toggle", {"entity_id": "switch.tasmota06"}))
# asyncio.create_task(
# self.hass.call_service("light", "turn_on", {"entity_id": "light.arbeitszimmer_fluter"}))
#elif message.touch_button == TouchButton.LEFT_FOOT:
# asyncio.create_task(
# self.hass.call_service("light", "turn_off", {"entity_id": "light.arbeitszimmer_fluter"}))
elif isinstance(message, TouchButtonRelease):
figure = self.mmstate.current_figure
eff_change = EffectRandomTwoColorInterpolationConfig() eff_change = EffectRandomTwoColorInterpolationConfig()
eff_static = EffectStaticConfig(ColorRGBW(0, 0, 0, 0), eff_static = EffectStaticConfig(ColorRGBW(0, 0, 0, 0),
*mouse_leds[message.touch_button]) *mouse_leds_index_ranges[message.touch_button])
if audio_player.is_playing(): if self.audio_player.is_playing():
eff_static.color = ccfg.primary primary_color, secondary_color, bg, accent = self.cfg["figures"][figure]["colors"]
protocol.mouse_led_effect(eff_static) eff_static.color = primary_color
self.protocol.mouse_led_effect(eff_static)
if audio_player.is_playing(): if self.audio_player.is_playing():
eff_change.color1 = ccfg.primary primary_color, secondary_color, bg, accent = self.cfg["figures"][figure]["colors"]
eff_change.color2 = ccfg.secondary eff_change.color1 = primary_color
eff_change.color2 = secondary_color
eff_change.start_with_existing = True eff_change.start_with_existing = True
protocol.mouse_led_effect(eff_change) self.protocol.mouse_led_effect(eff_change)
def _start_animation(self, primary_color, secondary_color): def _start_animation(self, primary_color, secondary_color):
ring_eff = EffectSwipeAndChange() ring_eff = EffectSwipeAndChange()
@ -193,13 +228,17 @@ class Controller:
def main(config_path): def main(config_path):
cfg = load_config(config_path) cfg = load_config(config_path)
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
hass = HomeAssistantClient(cfg["general"]["hass_url"], cfg["general"]["hass_token"], loop)
coro = serial_asyncio.create_serial_connection(loop, coro = serial_asyncio.create_serial_connection(loop,
MusicMouseProtocol, MusicMouseProtocol,
cfg["general"]["serial_port"], cfg["general"]["serial_port"],
baudrate=115200) baudrate=115200)
transport, protocol = loop.run_until_complete(coro) transport, protocol = loop.run_until_complete(coro)
controller = Controller(protocol, cfg) controller = Controller(protocol, hass, cfg)
loop.create_task(hass.connect())
return controller, loop return controller, loop

View File

@ -84,6 +84,9 @@ class AudioPlayer:
self.on_playlist_end_callback = None self.on_playlist_end_callback = None
self.volume_min = None
self.volume_max = None
def create_playlist(self, files): def create_playlist(self, files):
result = vlc.MediaList() result = vlc.MediaList()
for e in files: for e in files:
@ -120,11 +123,18 @@ class AudioPlayer:
#print("Callback from VLC", event, args, kwargs) #print("Callback from VLC", event, args, kwargs)
#print(event.meta_type, event.obj, event.type) #print(event.meta_type, event.obj, event.type)
def set_volume(self, volume):
if self.volume_min and volume < self.volume_min:
volume = self.volume_min
if self.volume_max and volume > self.volume_max:
volume = self.volume_max
print("volume", volume)
self.media_player.audio_set_volume(volume)
def set_volume_limits(self, vmin, vmax):
self.volume_min = vmin
self.volume_max = vmax
def change_volume(self, amount=1): def change_volume(self, amount=1):
vol = self.media_player.audio_get_volume() + amount vol = self.media_player.audio_get_volume() + amount
print("volume", vol) self.set_volume(vol)
if vol > 100:
vol = 100
if vol < 0:
vol = 0
self.media_player.audio_set_volume(vol)

View File

@ -42,6 +42,7 @@ struct MsgRfidTokenRead
struct MsgRotaryEncoder struct MsgRotaryEncoder
{ {
int32_t position; int32_t position;
int32_t increment;
uint8_t direction; uint8_t direction;
}; };

View File

@ -60,11 +60,20 @@ void setupRotaryEncoder()
ESP_ERROR_CHECK(rotary_encoder_set_queue(&info, eventQueueRotaryEncoder)); ESP_ERROR_CHECK(rotary_encoder_set_queue(&info, eventQueueRotaryEncoder));
} }
int32_t lastRotaryPosition = 0;
bool lastRotaryPositionValid = false;
void handleRotaryEncoder() void handleRotaryEncoder()
{ {
rotary_encoder_event_t event = {0}; rotary_encoder_event_t event = {0};
if (xQueueReceive(eventQueueRotaryEncoder, &event, 0) == pdTRUE) if (xQueueReceive(eventQueueRotaryEncoder, &event, 0) == pdTRUE)
sendMessageToHost(MsgRotaryEncoder{event.state.position, (uint8_t)(event.state.direction)}); {
int32_t increment = 0;
if (lastRotaryPositionValid)
increment = lastRotaryPosition - event.state.position;
sendMessageToHost(MsgRotaryEncoder{event.state.position, increment, (uint8_t)(event.state.direction)});
lastRotaryPositionValid = true;
lastRotaryPosition = event.state.position;
}
} }
// -------------------------------------------------- Buttons ---------------------------------------- // -------------------------------------------------- Buttons ----------------------------------------
@ -190,12 +199,13 @@ void handleTouchInputs()
touch_pad_read(TOUCH_PAD_RIGHT_FOOT, &touchRightFoot); touch_pad_read(TOUCH_PAD_RIGHT_FOOT, &touchRightFoot);
touch_pad_read(TOUCH_PAD_LEFT_EAR, &touchLeftEar); touch_pad_read(TOUCH_PAD_LEFT_EAR, &touchLeftEar);
touch_pad_read(TOUCH_PAD_RIGHT_EAR, &touchRightEar); touch_pad_read(TOUCH_PAD_RIGHT_EAR, &touchRightEar);
//Serial.printf("Feet %d %d, Ears %d, %d\n", touchLeftFoot, touchRightFoot, touchLeftEar, touchRightEar);
//delay(100);
bool currentState[4]; bool currentState[4];
currentState[int(TouchButton::LEFT_FOOT)] = touchLeftFoot < 380; currentState[int(TouchButton::LEFT_FOOT)] = touchLeftFoot < 380;
currentState[int(TouchButton::RIGHT_FOOT)] = touchRightFoot < 380; currentState[int(TouchButton::RIGHT_FOOT)] = touchRightFoot < 380;
currentState[int(TouchButton::LEFT_EAR)] = touchLeftEar < 430; currentState[int(TouchButton::LEFT_EAR)] = touchLeftEar < 430;
currentState[int(TouchButton::RIGHT_EAR)] = touchRightEar < 430; currentState[int(TouchButton::RIGHT_EAR)] = touchRightEar < 400;
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
{ {