class EnttecDmx(DmxOutput): stats = scales.collection('/output/enttecDmx', scales.PmfStat('write'), scales.PmfStat('update')) def __init__(self, uri, devicePath='/dev/dmx0', numChannels=80): DmxOutput.__init__(self, uri, numChannels) sys.path.append("dmx_usb_module") from dmx import Dmx self.dev = Dmx(devicePath) self.currentBuffer = '' self.lastLog = 0 self._loop() @stats.update.time() def update(self, values): now = time.time() if now > self.lastLog + 1: log.info('enttec %s', ' '.join(map(str, values))) self.lastLog = now # I was outputting on 76 and it was turning on the light at # dmx75. So I added the 0 byte. No notes explaining the footer byte. self.currentBuffer = '\x00' + ''.join(map(chr, values)) + "\x00" @stats.write.time() def sendDmx(self, buf): self.dev.write(self.currentBuffer) def countError(self): pass
def __init__(self, uri, devicePath='/dev/dmx0', numChannels=80): DmxOutput.__init__(self, uri, numChannels) sys.path.append("dmx_usb_module") from dmx import Dmx self.dev = Dmx(devicePath) self.currentBuffer = '' self.lastLog = 0 self._loop()
def dmxstartstop(self, frequency=1, onlystop=False, port='COM3'): print(f"model - dmxstartstop called with port: {port}") print(hasattr(self, 'dmx')) if not hasattr(self, 'dmx'): if onlystop: return else: self.dmx = Dmx(daemon=True, frequency=frequency, COM=port) self.dmx_worker = self.Dmx_Worker(self.dmx) if self.dmx.is_alive(): self.dmx_worker.stop() self.dmx.stop() del self.dmx del self.dmx_worker elif not onlystop: self.dmx.start() self.dmx_worker.start()
def __init__(self): self.brightness = 0 self.dmx = Dmx() #EnttecUsbDmxPro.EnttecUsbDmxPro() self.port = get_default_port() self.dmx.setPort(self.port, baud=250000) self.dmx.connect() # print 'EntTec serial number:', self.dmx.getWidgetSerialNumber() # self.dmx.setDebug('SerialBuffer', True) self.dmx.setChannel(CHANNEL_MASTER_CONTROL, MASTER_LAMP_OFF, autoRender=False) self.dmx.setChannel(CHANNEL_PAN_LOCATION, degrees_to_dmx(180), autoRender=False) # pan location self.dmx.setChannel(CHANNEL_TILT, tilt_to_dmx(0), autoRender=False) # tilt to 0 degrees (horizontal) self.dmx.setChannel(CHANNEL_SPEED, percent_to_dmx(25), autoRender=False) # set speed self.dmx.render()
class Model: def __init__(self, controller): super().__init__() self.controller = controller #self.dmx = Dmx(daemon=True, frequency=1) def dmxstartstop(self, frequency=1, onlystop=False, port='COM3'): print(f"model - dmxstartstop called with port: {port}") print(hasattr(self, 'dmx')) if not hasattr(self, 'dmx'): if onlystop: return else: self.dmx = Dmx(daemon=True, frequency=frequency, COM=port) self.dmx_worker = self.Dmx_Worker(self.dmx) if self.dmx.is_alive(): self.dmx_worker.stop() self.dmx.stop() del self.dmx del self.dmx_worker elif not onlystop: self.dmx.start() self.dmx_worker.start() def got_message(self, msg, eventlist): #eventlist=('follow','subscription','resub','prime_sub_gift', 'host','bits','raids','donation') print('Received message: ', msg) msgtype = msg['type'] if msgtype in eventlist: # self.chkvars[eventname]=tk.BooleanVar(value=self.controller.config.collection.data[eventname]['alert']) # self.eventChannel[eventname] = tk.IntVar(value=self.controller.config.collection.data[eventname]['dmxchannel']) # self.eventDmxValue[eventname] = tk.IntVar(value=self.controller.config.collection.data[eventname]['dmxvalue']) # self.eventSeconds[eventname] = tk.DoubleVar(value=self.controller.config.collection.data[eventname]['seconds']) # self.eventDefaultTo[eventname] = tk.IntVar(value=self.controller.config.collection.data[eventname]['default']) print(f"Found known event-type: {msgtype}") if self.controller.config.collection.data[msgtype]['alert']: dmx_settings = {} dmx_settings[ 'channel'] = self.controller.config.collection.data[ msgtype]['dmxchannel'] dmx_settings['value'] = self.controller.config.collection.data[ msgtype]['dmxvalue'] dmx_settings[ 'seconds'] = self.controller.config.collection.data[ msgtype]['seconds'] dmx_settings[ 'fallback'] = self.controller.config.collection.data[ msgtype]['default'] if 'secondsperunit' in ( self.controller.config.collection.data[msgtype]): if self.controller.config.collection.data[msgtype][ 'secondsperunit']: dmx_settings['multiplier'] = msg['message'][0][ 'amount'] else: dmx_settings['multiplier'] = 1 else: dmx_settings['multiplier'] = 1 pass self.controller.view.addToList( f"Setting DMX-Channel {dmx_settings['channel']} to {dmx_settings['value']} for {dmx_settings['seconds']}*{dmx_settings['multiplier']} = {float(dmx_settings['seconds'])*float(dmx_settings['multiplier'])} seconds, then back to {dmx_settings['fallback']}" ) self.dmx_worker.q.put(dmx_settings) else: print(f"Unknown event-type: {msg['type']}") self.controller.view.addToList( f"Unknown event-type: {msg['type']}") # async def do_dmx(self,channel,value,seconds,fallback,multiplier=1): # self.dmx.set_data(channel,value) # asyncio.sleep(seconds*multiplier) # self.dmx.set_data(channel,fallback) # pass class Dmx_Worker(threading.Thread): def __init__(self, dmx, *args, runSemaphore=True, **kwargs): super().__init__(*args, **kwargs) self.dmx = dmx self.q = queue.Queue() self.runSemaphore = runSemaphore def run(self): print("DMX_WORKER started") while True: item = self.q.get() if item == None: break #exit when queue receives item with value NONE from stop() function print(f'New Worker Item: {item}') self.dmx.set_data(item['channel'], item['value']) time.sleep(float(item['seconds']) * float(item['multiplier'])) self.dmx.set_data(item['channel'], item['fallback']) def stop(self): print("Worker stop called") self.q.put(None)
class Lighthouse(object): def __init__(self): self.brightness = 0 self.dmx = Dmx() #EnttecUsbDmxPro.EnttecUsbDmxPro() self.port = get_default_port() self.dmx.setPort(self.port, baud=250000) self.dmx.connect() # print 'EntTec serial number:', self.dmx.getWidgetSerialNumber() # self.dmx.setDebug('SerialBuffer', True) self.dmx.setChannel(CHANNEL_MASTER_CONTROL, MASTER_LAMP_OFF, autoRender=False) self.dmx.setChannel(CHANNEL_PAN_LOCATION, degrees_to_dmx(180), autoRender=False) # pan location self.dmx.setChannel(CHANNEL_TILT, tilt_to_dmx(0), autoRender=False) # tilt to 0 degrees (horizontal) self.dmx.setChannel(CHANNEL_SPEED, percent_to_dmx(25), autoRender=False) # set speed self.dmx.render() def set_lamp(self, int_brightness): """ Brightness is a percentage, 0-100% """ self.brightness = int_brightness if self.brightness == 0: self.dmx.setChannel(CHANNEL_MASTER_CONTROL, MASTER_LAMP_OFF, autoRender=False) self.dmx.render() return self.dmx.setChannel(CHANNEL_MASTER_CONTROL, MASTER_LAMP_ON, autoRender=False) self.dmx.setChannel(CHANNEL_BRIGHTNESS, brightness_percent_to_dmx(self.brightness), autoRender=False) self.dmx.render() def set_pan_position(self, position_degrees): """ Moves lamp to a specific position """ # Disable rotation # TODO - determine magic value that must be sent to stop rotating self.dmx.setChannel(CHANNEL_PAN_MOVMENT, 0, autoRender=False) position_degrees = reposition_from_pan_deadzone(position_degrees) self.dmx.setChannel(CHANNEL_PAN_LOCATION, degrees_to_dmx(position_degrees), autoRender=False) self.dmx.render() def set_rotation(self, clockwise, speed=100): """ Set rotation and speed TODO - assert speed < 50% if already moving """ self.dmx.setChannel(CHANNEL_SPEED, percent_to_dmx(0), autoRender=False) self.dmx.render() time.sleep(1) if clockwise: self.dmx.setChannel(CHANNEL_PAN_MOVMENT, PAN_CW, autoRender=False) else: self.dmx.setChannel(CHANNEL_PAN_MOVMENT, PAN_CCW, autoRender=False) self.dmx.setChannel(CHANNEL_SPEED, percent_to_dmx(speed), autoRender=False) self.dmx.render() def set_tilt(self, tilt_degrees): """ Set the lamp's tilt, in degrees. 0 is horizontal, 90 is vertical, 90+ is rotation in the other direction. The lowest it can go is -30 degrees. """ tilt_degrees = reposition_from_tilt_deadzone(tilt_degrees) self.dmx.setChannel(CHANNEL_TILT, tilt_to_dmx(tilt_degrees), autoRender=False) self.dmx.render() def set_speed(self, speed_percent): """ Set the speed in percent of dmx, range untested on actual lamp """ self.dmx.setChannel(CHANNEL_SPEED, percent_to_dmx(speed_percent), autoRender=False) self.dmx.render() def set_strobe(self, strobe_percent): """ Set the strobe percent of dmx, untested on actual lamp """ self.dmx.setChannel(CHANNEL_STROBE, percent_to_dmx(strobe_percent), autoRender=False) self.dmx.render() def set_idle(self, ignored): self.set_speed(0) self.set_lamp(95) self.set_strobe(0) self.set_tilt(5) time.sleep(.5) self.set_rotation(True, speed=50) def shutdown_light(self): """ It is important to stop the light, turn off the lamp and disconnect. """ self.set_rotation(True, speed=0) self.set_lamp(0) time.sleep(2) self.dmx.disconnect()