#!/usr/bin/env python # *-----------------------------------------------------------------------* # | | # | Copyright (c) 2022 by Paul Scherrer Institute (http://www.psi.ch) | # | Based on Zac great first implementation | # | Author Thierry Zamofing (thierry.zamofing@psi.ch) | # *-----------------------------------------------------------------------* import logging _log=logging.getLogger(__name__) import socket ''' Please do not leave the LEDs on longer than needed, especially the colored ones. I guess I have an issue with power dissipation on my board. For the white LEDs it should be ok. The lights communicate in hexidecimal, two 2bytes: byte 1: 0x00 get status 0x01 off 0x02 on 0x04 out (unused?) byte 2: 0x01 front white 0x02 front red 0x04 front green 0x08 front blue 0x10 back white ''' # commands stat= 0x00 off = 0x01 on = 0x02 # leds front = 0x01 red = 0x02 green = 0x04 blue = 0x08 back = 0x10 all = 0xff class IlluminationControl(object): def __init__(self,hostname: str="129.129.244.24",port: int=1003): if hostname is None: #simulated mode self._sim={'stat':0} _log.info('simulated mode:{}'.format(self._sim)) return self._hostname = hostname self._port = port self.connect() def connect(self): """creates a socket and connects to illumination controller""" # connect to XT-PICO self._socket=s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(1) try: s.connect((self._hostname, self._port)) except socket.timeout as e: _log.error(f"{e} can't connect to: {self._hostname}:{self._port}") def disconnect(self): try: self._socket.close() except AttributeError: pass def is_on(self, led_flags: int) -> bool: """check status for light state, see CONSTANTS STATUS_BITS_*""" s = self.status() return bool(s & led_flags) def send_command(self, cmd: bytes): try: s=self._socket except AttributeError: #simulated mode _log.info('simulated mode:{}'.format(cmd)) return try: self._socket.sendall(cmd) except (BrokenPipeError, OSError) as e: _log.warning("reconnecting lights") self.connect() try: self._socket.sendall(cmd) except Exception as e: _log.error("unrecoverable socket error: {}".format(e.args)) def status(self): try: s=self._socket except AttributeError: #simulated mode _log.debug('simulated mode') return self._sim['stat'] self.send_command(bytes((stat,all))) resp = self._socket.recv(1024) return resp[0]&0x1f def all(self,val): cmd = on if val else off self.send_command(bytes((cmd,all))) def front(self,val): cmd = on if val else off self.send_command(bytes((cmd,front))) def back(self,val): cmd = on if val else off self.send_command(bytes((cmd,back))) def red(self,val): cmd = on if val else off self.send_command(bytes((cmd,red))) def blue(self,val): cmd = on if val else off self.send_command(bytes((cmd,blue))) def green(self,val): cmd = on if val else off self.send_command(bytes((cmd,green))) if __name__ == "__main__": import argparse logging.basicConfig(level=logging.DEBUG,format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ') parser = argparse.ArgumentParser() parser.add_argument('-m', '--mode', help='mode string with characters: "frgbka" for front,red,green,blue,back,all') parser.add_argument("-t", "--test", help="test sequence", action="store_true") args = parser.parse_args() _log.info('Arguments:{}'.format(args.__dict__)) #Static IP 129.129.244.24 #HOST SAROP31-CINT-SWMX1 #MAC: 08:BB:CC.05:89:1A host = "129.129.244.24" port = 1003 leds = IlluminationControl(host,port) if args.test: leds.all(False) print(bin(leds.status()));time.sleep(1) leds.front(True) print(bin(leds.status()));time.sleep(1) leds.front(False); leds.red(True) print(bin(leds.status()));time.sleep(1) leds.red(False); leds.green(True) print(bin(leds.status()));time.sleep(1) leds.green(False); leds.blue(True) print(bin(leds.status()));time.sleep(1) leds.blue(False); leds.back(True) print(bin(leds.status()));time.sleep(1) leds.back(False) print(bin(leds.status()));time.sleep(1) else: leds.all(False) _log.debug('turn off all') if args.mode is not None: m=args.mode l=0 if 'f' in m: l|=front if 'r' in m: l|=red if 'g' in m: l|=green if 'b' in m: l|=blue if 'k' in m: l|=back if 'a' in m: l|=all leds.send_command(bytes((on,l))) _log.debug('turn on %s'%bin(l))