169 lines
4.7 KiB
Python
Executable File
169 lines
4.7 KiB
Python
Executable File
#!/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.221.92",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)
|
|
s.connect((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.info('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.debug(args)
|
|
host = "129.129.221.92"
|
|
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))
|
|
|