diff --git a/src/light9/collector/output.py b/src/light9/collector/output.py --- a/src/light9/collector/output.py +++ b/src/light9/collector/output.py @@ -192,7 +192,7 @@ class Udmx(BackgroundLoopOutput): from pyudmx import pyudmx self.dev = pyudmx.uDMXDevice() if not self.dev.open(bus=self.bus, address=self.address): - raise ValueError("dmx open failed") + raise ValueError(f"dmx open(bus={self.bus}, address={self.address}) failed") log.info(f'opened {self.dev}') metrics('connected', output=self.shortId()).set(1) metrics('reconnections', output=self.shortId()).inc() @@ -252,6 +252,9 @@ class Udmx(BackgroundLoopOutput): self.reconnect() return + if e.errno == 110: # USBTimeoutError + return self.crash() + raise dt = time.time() - t1 if dt > 1 / self.rate * 1.5: diff --git a/src/light9/collector/service.py b/src/light9/collector/service.py --- a/src/light9/collector/service.py +++ b/src/light9/collector/service.py @@ -9,6 +9,8 @@ Input can be over http or zmq. import asyncio import functools import logging +import os +import stat import subprocess import traceback from typing import List @@ -94,7 +96,10 @@ def findDevice(): words = line.split(':')[0].split() dev = f'/dev/bus/usb/{words[1]}/{words[3]}' log.info(f'device will be {dev}') - return dev, int(words[3]) + st = os.stat(dev) + if not (st.st_mode & (stat.S_IWUSR | stat.S_IRUSR)): + raise ValueError(f'{dev} has insufficient stat ({stat.filemode(st.st_mode)})') + return dev, int(words[1]), int(words[3]) raise ValueError("no matching uDMX found") @@ -107,7 +112,7 @@ def main(): graph = SyncedGraph(networking.rdfdb.url, "collector") - devPath, usbAddress = findDevice() + devPath, bus, usbAddress = findDevice() # if user doesn't have r/w, fail now try: # todo: drive outputs with config files @@ -117,7 +122,7 @@ def main(): # port=6445, # rate=rate), #sudo chmod a+rw /dev/bus/usb/003/021 - Udmx(L9['output/dmxA/'], bus=3, address=usbAddress, lastDmxChannel=200, rate=RATE), + Udmx(L9['output/dmxA/'], bus=bus, address=usbAddress, lastDmxChannel=200, rate=RATE), ] except Exception: log.error("setting up outputs:")