48 lines
1.1 KiB
Python
48 lines
1.1 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
from dataclasses import dataclass
|
|
from typing import Any
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class PicoEvent:
|
|
button: int
|
|
pin: int
|
|
event: str
|
|
pressed: bool
|
|
|
|
def to_dict(self) -> dict[str, Any]:
|
|
return {
|
|
"button": self.button,
|
|
"pin": self.pin,
|
|
"event": self.event,
|
|
"pressed": self.pressed,
|
|
}
|
|
|
|
|
|
def parse_pico_line(raw_line: str) -> PicoEvent | None:
|
|
try:
|
|
payload = json.loads(raw_line)
|
|
except json.JSONDecodeError:
|
|
return None
|
|
|
|
if not isinstance(payload, dict):
|
|
return None
|
|
if not {"button", "pin", "event", "pressed"}.issubset(payload):
|
|
return None
|
|
if payload["event"] not in {"down", "up"}:
|
|
return None
|
|
|
|
try:
|
|
button = int(payload["button"])
|
|
pin = int(payload["pin"])
|
|
except (TypeError, ValueError):
|
|
return None
|
|
|
|
if button < 1 or button > 10:
|
|
return None
|
|
|
|
return PicoEvent(button=button, pin=pin, event=payload["event"], pressed=bool(payload["pressed"]))
|
|
|