Touch events & rotary events to host

This commit is contained in:
Martin Bauer
2021-12-15 22:47:28 +01:00
parent f9f1244807
commit ee632664e6
7 changed files with 307 additions and 83 deletions

View File

@@ -10,8 +10,9 @@ MAGIC_TOKEN_FW_TO_HOST = 0x10c65631
class MessageFwToHost(Enum):
RFID_TOKEN_READ = 0
BUTTON_NORMAL_PRESS = 1
ROTARY_ENCODER = 2
ROTARY_ENCODER = 1
TOUCH_BUTTON_PRESS = 2
TOUCH_BUTTON_RELEASE = 3
class MessageHostToFw(Enum):
@@ -21,6 +22,13 @@ class MessageHostToFw(Enum):
LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION = 3
class TouchButton(Enum):
LEFT_FOOT = 0
RIGHT_FOOT = 1
LEFT_EAR = 2
RIGHT_EAR = 3
outgoing_msg_map = {
EffectStaticConfig: 0,
EffectAlexaSwipeConfig: 1,
@@ -38,7 +46,38 @@ class RfidTokenRead:
return "RFID Token (" + " ".join(f"{v:02x}" for v in self.id) + ")"
incomingMsgMap = {0: RfidTokenRead}
class RotaryEncoderEvent:
def __init__(self, msg_content: bytes):
self.position, self.direction = struct.unpack("<iB", msg_content)
def __repr__(self):
return f"Rotary event: pos {self.position}, dir {self.direction}"
class TouchButtonPress:
def __init__(self, msg_content: bytes):
val = int(msg_content[0])
self.touch_button = TouchButton(val)
def __repr__(self) -> str:
return "Pressed " + repr(self.touch_button)
class TouchButtonRelease:
def __init__(self, msg_content: bytes):
val = int(msg_content[0])
self.touch_button = TouchButton(val)
def __repr__(self) -> str:
return "Released " + repr(self.touch_button)
incomingMsgMap = {
0: RfidTokenRead,
1: RotaryEncoderEvent,
2: TouchButtonPress,
3: TouchButtonRelease,
}
class MusicMouseProtocol(asyncio.Protocol):

View File

@@ -44,9 +44,11 @@ class ColorHSV:
@dataclass
class EffectStaticConfig:
color: ColorRGBW
begin: int = 0
end: int = 0
def as_bytes(self) -> bytes:
return self.color.as_bytes()
return self.color.as_bytes() + struct.pack("<HH", self.begin, self.end)
@dataclass

View File

@@ -13,30 +13,59 @@ MUSIC_FOLDER = "/home/martin/code/musicmouse/espmusicmouse/host_driver/music"
audio_player = AudioPlayer()
rfid_token_map = {
bytes.fromhex("0000000000"): "None",
bytes.fromhex("88041174e9"): "elefant",
bytes.fromhex("8804ce7230"): "fuchs",
bytes.fromhex("88040d71f0"): "eule",
}
playlists = {
fig: audio_player.create_playlist(glob(os.path.join(MUSIC_FOLDER, fig, "*.mp3")))
for fig in rfid_token_map.values()
}
mouse_leds = {
'right_foot': (0, 6),
'left_foot': (6, 6 + 6),
'left_ear': (6 + 6, 6 + 6 + 16),
'right_ear': (6 + 6 + 16, 6 + 6 + 16 + 17),
}
def set_mouse_leds(protocol, position: str, color: ColorRGBW):
start, end = mouse_leds[position]
protocol.send_message(EffectStaticConfig(color, start, end))
def on_music_end_callback(protocol):
eff = EffectAlexaSwipeConfig()
eff.forward = False
protocol.send_message(eff)
def on_firmware_msg(protocol, message):
print("Got message", message)
if isinstance(message, RfidTokenRead) and message.id in rfid_token_map:
if rfid_token_map[message.id] == "None":
if isinstance(message, RfidTokenRead) and message.id == bytes.fromhex("0000000000"):
if audio_player.is_playing():
eff = EffectAlexaSwipeConfig()
eff.forward = False
print("Nothing")
protocol.send_message(eff)
audio_player.pause()
else:
eff = EffectSwipeAndChange()
eff.swipe.primary_color = ColorRGBW(1, 1, 0, 0)
protocol.send_message(eff)
figure = rfid_token_map[message.id]
glob_result = glob(os.path.join(MUSIC_FOLDER, figure, "*.mp3"))
audio_player.set_file(glob_result[0])
audio_player.play()
eff = EffectStaticConfig(ColorRGBW(0, 0, 0, 0))
protocol.send_message(eff)
audio_player.pause()
if isinstance(message, RfidTokenRead) and message.id in rfid_token_map:
eff = EffectSwipeAndChange()
eff.swipe.primary_color = ColorRGBW(1, 1, 0, 0)
figure = rfid_token_map[message.id]
if figure == "eule":
eff.swipe.primary_color = ColorRGBW(0.96, 0.7, 0, 0)
eff.swipe.secondary_color = ColorRGBW(0.96, 0.7, 0, 0)
eff.swipe.swipe_speed = 180
eff.swipe.bell_curve_width_in_leds = 6
protocol.send_message(eff)
audio_player.set_playlist(playlists[figure])
audio_player.play_from_start()
loop = asyncio.get_event_loop()
@@ -46,5 +75,8 @@ coro = serial_asyncio.create_serial_connection(loop,
baudrate=115200)
transport, protocol = loop.run_until_complete(coro)
protocol.register_message_callback(on_firmware_msg)
audio_player.on_playlist_end_callback = lambda: on_music_end_callback(protocol)
loop.run_forever()
loop.close()

View File

@@ -1,17 +1,115 @@
import vlc
all_events = (
vlc.EventType.MediaDiscovererEnded,
vlc.EventType.MediaDiscovererStarted,
vlc.EventType.MediaDurationChanged,
vlc.EventType.MediaFreed,
vlc.EventType.MediaListEndReached,
vlc.EventType.MediaListItemAdded,
vlc.EventType.MediaListItemDeleted,
vlc.EventType.MediaListPlayerNextItemSet,
vlc.EventType.MediaListPlayerPlayed,
vlc.EventType.MediaListPlayerStopped,
vlc.EventType.MediaListViewItemAdded,
vlc.EventType.MediaListViewItemDeleted,
vlc.EventType.MediaListViewWillAddItem,
vlc.EventType.MediaListViewWillDeleteItem,
vlc.EventType.MediaListWillAddItem,
vlc.EventType.MediaListWillDeleteItem,
vlc.EventType.MediaMetaChanged,
vlc.EventType.MediaParsedChanged,
vlc.EventType.MediaPlayerAudioDevice,
vlc.EventType.MediaPlayerAudioVolume,
vlc.EventType.MediaPlayerBackward,
vlc.EventType.MediaPlayerBuffering,
vlc.EventType.MediaPlayerChapterChanged,
vlc.EventType.MediaPlayerCorked,
vlc.EventType.MediaPlayerESAdded,
vlc.EventType.MediaPlayerESDeleted,
vlc.EventType.MediaPlayerESSelected,
vlc.EventType.MediaPlayerEncounteredError,
vlc.EventType.MediaPlayerEndReached,
vlc.EventType.MediaPlayerForward,
#vlc.EventType.MediaPlayerLengthChanged,
vlc.EventType.MediaPlayerMediaChanged,
vlc.EventType.MediaPlayerMuted,
vlc.EventType.MediaPlayerNothingSpecial,
vlc.EventType.MediaPlayerOpening,
vlc.EventType.MediaPlayerPausableChanged,
vlc.EventType.MediaPlayerPaused,
vlc.EventType.MediaPlayerPlaying,
#vlc.EventType.MediaPlayerPositionChanged,
vlc.EventType.MediaPlayerScrambledChanged,
vlc.EventType.MediaPlayerSeekableChanged,
vlc.EventType.MediaPlayerSnapshotTaken,
vlc.EventType.MediaPlayerStopped,
#vlc.EventType.MediaPlayerTimeChanged,
vlc.EventType.MediaPlayerTitleChanged,
vlc.EventType.MediaPlayerUncorked,
vlc.EventType.MediaPlayerUnmuted,
vlc.EventType.MediaPlayerVout,
vlc.EventType.MediaStateChanged,
vlc.EventType.MediaSubItemAdded,
vlc.EventType.MediaSubItemTreeAdded,
vlc.EventType.RendererDiscovererItemAdded,
vlc.EventType.RendererDiscovererItemDeleted,
vlc.EventType.VlmMediaAdded,
vlc.EventType.VlmMediaChanged,
vlc.EventType.VlmMediaInstanceStarted,
vlc.EventType.VlmMediaInstanceStatusEnd,
vlc.EventType.VlmMediaInstanceStatusError,
vlc.EventType.VlmMediaInstanceStatusInit,
vlc.EventType.VlmMediaInstanceStatusOpening,
vlc.EventType.VlmMediaInstanceStatusPause,
vlc.EventType.VlmMediaInstanceStatusPlaying,
vlc.EventType.VlmMediaInstanceStopped,
vlc.EventType.VlmMediaRemoved,
)
class AudioPlayer:
def __init__(self):
self.instance = vlc.Instance()
self.mediaplayer = self.instance.media_player_new()
self.media_list_player = self.instance.media_list_player_new()
self.media_player = self.media_list_player.get_media_player()
def set_file(self, filename):
media = self.instance.media_new(filename)
self.mediaplayer.set_media(media)
evm = self.media_player.event_manager()
evm.event_attach(vlc.EventType.MediaPlayerEndReached, self._callback)
self.on_playlist_end_callback = None
def create_playlist(self, files):
result = vlc.MediaList()
for e in files:
result.add_media(self.instance.media_new(e))
return result
def set_playlist(self, media_list):
self.media_list_player.set_media_list(media_list)
def next(self):
self.media_list_player.next()
def previous(self):
self.media_list_player.previous()
def play(self):
self.mediaplayer.play()
self.media_list_player.play()
def play_from_start(self):
self.media_list_player.play_item_at_index(0)
def is_playing(self):
return self.media_list_player.is_playing()
def pause(self):
self.mediaplayer.pause()
self.media_list_player.pause()
def _callback(self, event, *args, **kwargs):
if event.type == vlc.EventType.MediaPlayerEndReached:
print("End reached")
if self.on_playlist_end_callback:
self.on_playlist_end_callback()
#print("Callback from VLC", event, args, kwargs)
#print(event.meta_type, event.obj, event.type)