108 lines
2.5 KiB
Python
108 lines
2.5 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", "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, diskState: DiskState) -> None:
|
|
yellowCtr: int = 0
|
|
while not stopEvent.is_set():
|
|
if diskState == "disconnected":
|
|
yellow.off()
|
|
elif diskState == "connected":
|
|
yellow.on()
|
|
elif diskState == "pairing":
|
|
if yellowCtr % 2 == 0:
|
|
yellow.on()
|
|
else:
|
|
yellow.off()
|
|
sleep(1)
|
|
|
|
|
|
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()
|