Files
SwissMX/illumination.py
2022-08-16 07:00:30 +02:00

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.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__))
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))