Files
plotcctv/main.py

129 lines
2.9 KiB
Python

from queue import Empty, Queue
from time import sleep
from typing import Literal
import pyudev
from gpiozero import LED
from threading import Thread, Event
from dataclasses import dataclass
red = LED(17)
yellow = LED(27)
blue = LED(22)
@dataclass
class DiskEvent:
event: str
node: str
serial: str
DiskState = Literal["disconnected", "pairing", "connecting", "connected"]
def diskPollWorker(stopEvent: Event, eventQueue: Queue) -> None:
context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by(subsystem="block")
print("Waiting for disks...")
for device in iter(monitor.poll, None):
if device.action == "add" and device.device_type == "disk":
eventQueue.put(
DiskEvent(
event="connected",
node=f"{device.device_node}",
serial=f"{device.get('ID_SERIAL_SHORT', 'Unknown')}",
)
)
elif device.action == "remove" and device.device_type == "disk":
eventQueue.put(
DiskEvent(
event="disconnected",
node=f"{device.device_node}",
serial=f"{device.get('ID_SERIAL_SHORT', 'Unknown')}",
)
)
if stopEvent.is_set():
return
def ledWorker(stopEvent: Event, state) -> None:
yellowCtr = 0
previousState: DiskState | None = None
while not stopEvent.is_set():
diskState: DiskState = state.diskState
if diskState != previousState:
yellowCtr = 0
previousState = diskState
if diskState == "disconnected":
yellow.off()
elif diskState == "connected":
yellow.on()
elif diskState == "pairing":
if yellowCtr % 2 == 0:
yellow.on()
else:
yellow.off()
elif diskState == "connecting":
if yellowCtr % 4 < 2:
yellow.on()
else:
yellow.off()
yellowCtr += 1
stopEvent.wait(0.25)
yellow.off()
def main() -> None:
try:
stopEvent = Event()
diskEventQueue: Queue[DiskEvent] = Queue()
diskState: DiskState = "pairing"
diskPollThread = Thread(
target=diskPollWorker,
name="disk_poll_thread",
args=(stopEvent, diskEventQueue),
daemon=True,
)
diskPollThread.start()
ledThread = Thread(
target=ledWorker,
name="led_thread",
args=(stopEvent, diskState),
daemon=True,
)
ledThread.start()
while True:
try:
event = diskEventQueue.get_nowait()
print(event)
except Empty:
sleep(1)
finally:
stopEvent.set()
return
if __name__ == "__main__":
main()