musicmouse/espmusicmouse/host_driver/host_driver.py

98 lines
2.8 KiB
Python
Raw Normal View History

2021-11-25 22:20:04 +01:00
import asyncio
from enum import Enum
import struct
2021-11-27 19:04:08 +01:00
from led_cmds import *
2021-11-25 22:20:04 +01:00
MAGIC_TOKEN_HOST_TO_FW = 0x1d6379e3
MAGIC_TOKEN_FW_TO_HOST = 0x10c65631
class MessageFwToHost(Enum):
RFID_TOKEN_READ = 0
BUTTON_NORMAL_PRESS = 1
ROTARY_ENCODER = 2
class MessageHostToFw(Enum):
LED_WHEEL_EFFECT_STATIC = 0
LED_WHEEL_EFFECT_ALEXA_SWIPE = 1
LED_WHEEL_EFFECT_CIRCULAR = 2
LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION = 3
2021-11-27 21:18:54 +01:00
outgoing_msg_map = {
2021-11-27 19:04:08 +01:00
EffectStaticConfig: 0,
EffectAlexaSwipeConfig: 1,
EffectCircularConfig: 2,
2021-11-27 21:18:54 +01:00
EffectRandomTwoColorInterpolationConfig: 3,
EffectSwipeAndChange: 4,
2021-11-27 19:04:08 +01:00
}
2021-11-25 22:20:04 +01:00
2021-11-27 19:04:08 +01:00
class RfidTokenRead:
def __init__(self, id: bytes):
self.id = id
2021-11-25 22:20:04 +01:00
2021-11-27 19:04:08 +01:00
def __repr__(self):
return "RFID Token (" + " ".join(f"{v:02x}" for v in self.id) + ")"
2021-11-25 22:20:04 +01:00
2021-11-27 19:04:08 +01:00
incomingMsgMap = {0: RfidTokenRead}
2021-11-25 22:20:04 +01:00
class MusicMouseProtocol(asyncio.Protocol):
2021-11-27 21:18:54 +01:00
def __init__(self):
super()
self._msg_callback = None
def register_message_callback(self, cb):
self._msg_callback = cb
2021-11-25 22:20:04 +01:00
def connection_made(self, transport):
self.transport = transport
2021-11-27 19:04:08 +01:00
self.in_buff = bytes()
2021-11-25 22:20:04 +01:00
def send_message(self, message):
msg_content = message.as_bytes()
2021-11-27 21:18:54 +01:00
header = struct.pack("<IBH", MAGIC_TOKEN_HOST_TO_FW, outgoing_msg_map[type(message)],
2021-11-25 22:20:04 +01:00
len(msg_content))
self.transport.write(header + msg_content)
def data_received(self, data):
2021-11-27 19:04:08 +01:00
self.in_buff += data
self._parse_message()
2021-11-25 22:20:04 +01:00
def connection_lost(self, exc):
print('port closed')
self.transport.loop.stop()
def pause_writing(self):
print('pause writing')
print(self.transport.get_write_buffer_size())
def resume_writing(self):
print(self.transport.get_write_buffer_size())
print('resume writing')
2021-11-27 19:04:08 +01:00
def _parse_message(self):
HEADER_SIZE = 4 + 1 + 2
if len(self.in_buff) == 0:
return
if len(self.in_buff) >= HEADER_SIZE:
token, msg_type, msg_size = struct.unpack("<IBH", self.in_buff[:HEADER_SIZE])
if token == MAGIC_TOKEN_FW_TO_HOST and len(self.in_buff) >= HEADER_SIZE + msg_size:
self._on_msg_receive(msg_type, self.in_buff[HEADER_SIZE:HEADER_SIZE + msg_size])
self.in_buff = self.in_buff[HEADER_SIZE + msg_size:]
else:
idx = self.in_buff.find("\n".encode())
if idx >= 0:
text_msg = self.in_buff[:idx]
print("LOG:", text_msg.decode())
self.in_buff = self.in_buff[idx + 1:]
def _on_msg_receive(self, msg_type, msg_payload):
parsed_msg = incomingMsgMap[msg_type](msg_payload)
2021-11-27 21:18:54 +01:00
if self._msg_callback is not None:
self._msg_callback(self, parsed_msg)