From 6ce567f7ba5aa7c97701e54e34648c5c3f0477b8 Mon Sep 17 00:00:00 2001 From: Jens Janssen Date: Fri, 8 Feb 2019 15:34:32 +0100 Subject: [PATCH 1/7] PRJ: bump to version v3.0.1.dev0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 4a36342fc..763327302 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0 +3.0.1.dev0 From 1d42f073b94936c1eb5904dac04a60f44ac4253f Mon Sep 17 00:00:00 2001 From: Jens Janssen Date: Fri, 8 Feb 2019 16:05:29 +0100 Subject: [PATCH 2/7] PRJ: remove deploy from travis, not working --- .travis.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 212712f47..3805d4e9e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -48,13 +48,3 @@ script: after_success: - coveralls - -deploy: - provider: pypi - user: davidlp - password: - secure: EWWzZuUU5hJAd9iVPr4kPYbs1wbm7D8eVU596GUH8ZI/Q4seXsYeL+Pi++FI6M268qNUGJuVsvWbU5S+/E74VmIeU3b0n6BNSfUas0tSqMmazN/Sj0iMtGJ3Tll5Z7JfPK2RbZfBvSHN5T9W5RXz7M2US0x88ATrNVt3iuRNqWQ= - on: - tags: true - repo: SiLab-Bonn/basil - distributions: sdist bdist_wheel From 0b00265113cc92560f9d91a7e7cce0fe9b7dd44b Mon Sep 17 00:00:00 2001 From: Jens Janssen Date: Fri, 8 Feb 2019 16:25:57 +0100 Subject: [PATCH 3/7] PRJ: adding deploy to travis, this time with skip_existing --- .travis.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.travis.yml b/.travis.yml index 3805d4e9e..67f2c280b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -48,3 +48,14 @@ script: after_success: - coveralls + +deploy: + provider: pypi + user: davidlp + password: + secure: EWWzZuUU5hJAd9iVPr4kPYbs1wbm7D8eVU596GUH8ZI/Q4seXsYeL+Pi++FI6M268qNUGJuVsvWbU5S+/E74VmIeU3b0n6BNSfUas0tSqMmazN/Sj0iMtGJ3Tll5Z7JfPK2RbZfBvSHN5T9W5RXz7M2US0x88ATrNVt3iuRNqWQ= + on: + tags: true + repo: SiLab-Bonn/basil + skip_existing: true + distributions: sdist bdist_wheel From 8747a95ef1207f96c864f2d131b4c44e82ee5593 Mon Sep 17 00:00:00 2001 From: Jens Janssen Date: Fri, 8 Feb 2019 16:33:52 +0100 Subject: [PATCH 4/7] PRJ: specify supported Python versions in setup.py --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 184a5fb6a..f6de8671e 100644 --- a/setup.py +++ b/setup.py @@ -32,6 +32,7 @@ def package_files(directory): setup( name='basil_daq', version=version, + python_requires='>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*', description='Basil - a data acquisition and system testing framework', url='https://github.com/SiLab-Bonn/basil', license='BSD 3-Clause ("BSD New" or "BSD Simplified") License', From 7c5df007d84db20c85f45f48d1947a3a6e152f84 Mon Sep 17 00:00:00 2001 From: thirono Date: Mon, 25 Mar 2019 13:17:45 +0100 Subject: [PATCH 5/7] ENH: add a switch to aviod power reset (and harm CMOS active sensor) at initialization --- basil/HL/GPAC.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/basil/HL/GPAC.py b/basil/HL/GPAC.py index 6ef4c559a..e7100c120 100644 --- a/basil/HL/GPAC.py +++ b/basil/HL/GPAC.py @@ -96,6 +96,16 @@ def __init__(self, intf, conf): super(PowerGpio, self).__init__(intf, conf) self.PCA9554_ADD = self.POWER_GPIO_ADD self.GPIO_CFG = self.POWER_GPIO_CFG + self._init.setdefault('no_power_reset', False) + def init(self): + self._intf.write(self._base_addr + self.PCA9554_ADD, (self.PCA9554_CFG, self.GPIO_CFG)) + if self._init['no_power_reset']==False: + logging.info("########GPAC ##########") + logging.info("########POWER RESET!!!!!##########") + self._intf.write(self._base_addr + self.PCA9554_ADD, (self.PCA9554_OUT, 0x00)) + else: + logging.info("########GPAC #####") + logging.info("########SKIPPING POWER RESET #####") class AdcMuxGpio(GpioPca9554): From c4aff952be96f32c18a12ddc4bee448ec2a2001b Mon Sep 17 00:00:00 2001 From: Christian Bespin Date: Fri, 29 Mar 2019 16:05:31 +0100 Subject: [PATCH 6/7] ENH: Add module to control ISO-DEBYEFLEX3003 X-Ray machine --- basil/HL/debyeflex3003.py | 186 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 basil/HL/debyeflex3003.py diff --git a/basil/HL/debyeflex3003.py b/basil/HL/debyeflex3003.py new file mode 100644 index 000000000..895ef1c38 --- /dev/null +++ b/basil/HL/debyeflex3003.py @@ -0,0 +1,186 @@ +# +# ------------------------------------------------------------ +# Copyright (c) All rights reserved +# SiLab, Institute of Physics, University of Bonn +# ------------------------------------------------------------ +# + +from basil.HL.RegisterHardwareLayer import HardwareLayer +import logging + + +class debyeflex3003(HardwareLayer): + + """Driver for the ISO-DEBYEFLEX 3003 X-Ray tube. + A simple protocol via RS 232 serial port is used with 9600 baud rate. + """ + + def __init__(self, intf, conf): + super(debyeflex3003, self).__init__(intf, conf) + + def init(self): + super(debyeflex3003, self).init() + + def read(self): + ret = self._intf.read() + if ret[-1:] != "\r": + print("debyeflex3003.read() terminator error") + return ret[1:-1] + + def write(self, cmd): + self._intf.write(str(cmd)) + + def get_nominal_current(self): + """Read nominal current in mA. + """ + self.write("CN") + curr = self.read() + return int(curr) / 1000. + + def get_actual_current(self): + """Read actual current in mA. + """ + self.write("CA") + curr = self.read() + return int(curr) / 1000. + + def set_current(self, curr): + """Set current in mA + """ + if curr > 80 or curr < 0: + raise ValueError("Illegal value for tube current (0 - 80 mA)") + else: + self.write("SC:{:02d}".format(int(curr))) + logging.info("Set tube current to {:.1f} mA".format(self.get_nominal_current())) + + def get_nominal_voltage(self): + """Read nominal voltage in kV. + """ + self.write("VN") + vol = self.read() + return int(vol) / 1000. + + def get_actual_voltage(self): + """Read actual voltage in kV. + """ + self.write("VA") + vol = self.read() + return int(vol) / 1000. + + def set_voltage(self, vol): + """Set high voltage in kV + """ + if vol > 60 or vol < 0: + raise ValueError("Illegal value for tube voltage (0 - 60 kV)") + else: + self.write("SV:{:02d}".format(vol)) + logging.info("Set tube voltage to {:.1f} kV".format(self.get_nominal_voltage())) + + def set_highvoltage_on(self): + self.write("HV:1") + + def set_highvoltage_off(self): + self.write("HV:0") + + def open_shutter(self, shutter=1): + """Open the shutter with given number. Only shuttter=1 supported from hardware currently + """ + if not isinstance(shutter, int): + raise TypeError("Invalid type for shutter number") + elif shutter > 4 or shutter < 1: + raise ValueError("Invalid value for shutter number") + else: + self.write("OS:{:1d}".format(shutter)) + logging.info("Opened shutter number {:1d}".format(shutter)) + + def close_shutter(self, shutter=1): + """Close the shutter with given number. Only shuttter=1 supported from hardware currently + """ + if not isinstance(shutter, int): + raise TypeError("Invalid type for shutter number") + elif shutter > 4 or shutter < 1: + raise ValueError("Invalid value for shutter number") + else: + self.write("CS:{:1d}".format(shutter)) + logging.info("Closed shutter number {:1d}".format(shutter)) + + def start_timer(self, timer=1): + """Start the timer with the given number (corresponds to shutter number) + """ + if not isinstance(timer, int): + raise TypeError("Invalid type for timer number") + elif timer > 4 or timer < 1: + raise ValueError("Invalid value for timer number") + else: + self.write("TS:{:1d}".format(timer)) + logging.info("Started timer number {:1d}".format(timer)) + + def stop_timer(self, timer=1): + """Stop the timer with the given number (corresponds to shutter number) + """ + if not isinstance(timer, int): + raise TypeError("Invalid type for timer number") + elif timer > 4 or timer < 1: + raise ValueError("Invalid value for timer number") + else: + self.write("TE:{:1d}".format(timer)) + logging.info("Stopped timer number {:1d}".format(timer)) + + def set_timer(self, timer=1, dur=3600): + """Set the timer with the given number (corresponds to shutter number) to the given duration (in s) + """ + if not isinstance(timer, int): + raise TypeError("Invalid type for timer number") + elif not isinstance(dur, int): + raise TypeError("Illegal type for duration") + elif timer > 4 or timer < 1: + raise ValueError("Invalid value for timer number") + else: + h = dur // 3600 + m = (dur % 3600) // 60 + s = (dur % 3600) % 60 + self.write("TP:{:1d},{:02d},{:02d},{:02d}".format(timer, h, m, s)) + time = self.get_nominal_time(timer) + logging.info("Set timer number {:1d} to {:02d}:{:02d}:{:02d} (HH:MM:SS)".format( + timer, time // 3600, (time % 3600) // 60, (time % 3600) % 60) + ) + + def get_actual_time(self, timer=1): + """Get the actual time of the given timer in s + """ + if not isinstance(timer, int): + raise TypeError("Invalid type for timer number") + elif timer > 4 or timer < 1: + raise ValueError("Invalid value for timer number (1, 2, 3, 4)") + else: + self.write("TA:{:1d}".format(timer)) + time = self.read() + return int(time) + + def get_nominal_time(self, timer=1): + """Get the nominal time of the given timer in s + """ + if not isinstance(timer, int): + raise TypeError("Invalid type for timer number") + elif timer > 4 or timer < 1: + raise ValueError("Invalid value for timer number (1, 2, 3, 4)") + else: + self.write("TN:{:1d}".format(timer)) + time = self.read() + return int(time) + + def lock_keyboard(self): + """Locks the hardware keyboard on the device. Only STOP key still works. + """ + self.write("KB:0") + + def unlock_keyboard(self): + self.write("KB:1") + + def get_status(self, status_word): + """ Get a pre-selected range of status parameters + """ + self.write("SR:{:02d}".format(status_word)) + response = self.read() + status = bin(int(response[7:10]))[2:].zfill(8) # Convert response to 8 char long string of binary values + logging.info("Status word {:02d}: {:8s}".format(status_word, status)) From e480eac57038e17789ec16961bac76b315b1e8a7 Mon Sep 17 00:00:00 2001 From: thirono Date: Wed, 15 May 2019 19:57:52 +0200 Subject: [PATCH 7/7] EHN: add chiller (julaboF32HD) --- basil/HL/julaboF32HD.py | 73 +++++++++++++++++++++++++++ examples/lab_devices/julaboF32HD.py | 24 +++++++++ examples/lab_devices/julaboF32HD.yaml | 19 +++++++ 3 files changed, 116 insertions(+) create mode 100644 basil/HL/julaboF32HD.py create mode 100644 examples/lab_devices/julaboF32HD.py create mode 100644 examples/lab_devices/julaboF32HD.yaml diff --git a/basil/HL/julaboF32HD.py b/basil/HL/julaboF32HD.py new file mode 100644 index 000000000..38eedc355 --- /dev/null +++ b/basil/HL/julaboF32HD.py @@ -0,0 +1,73 @@ +# +# ------------------------------------------------------------ +# Copyright (c) All rights reserved +# SiLab, Institute of Physics, University of Bonn +# ------------------------------------------------------------ +# + +from basil.HL.RegisterHardwareLayer import HardwareLayer +import logging +import time +import string + +class julaboF32HD(HardwareLayer): + + """Driver for the Julabo F32-HD tillar. + A simple protocol via RS 232 serial port is used with 4800 baud rate. + """ + + def __init__(self, intf, conf): + super(julaboF32HD, self).__init__(intf, conf) + self.pre_time=time.time() + + def init(self): + super(julaboF32HD, self).init() + + def read(self): + ret = self._intf.read() + if len(ret)<2 or ret[-2:] != "\r\n": + print("julabo.read() terminator error") + return ret[:-2] + + def write(self, cmd): + if time.time()-self.pre_time<1.0: + time.sleep(1.0) + self._intf.write(str(cmd)) + self.pre_time=time.time() + + def get_identifier(self): + """Read identifier + """ + self.write("version") + ret = self.read() + return ret + + def start_thermostat(self,start=True): + """ start tiller + """ + if start==True: + self.write("out_mode_05 1") + else: + self.write("out_mode_05 0") + + def stop_thermostat(self): + """ stop tiller + """ + self.start_thermostat(False) + + def get_status(self): + """ Get status + """ + self.write("status") + ret = self.read() + logging.debug("status:{:s}".format(ret)) + try: + tmp=ret.split(" ", 1) + status=int(tmp[0]) + status_str=tmp[1:] + except: + print("julabo.get_status() wrong format ".format(repr(ret))) + status=-99 + status_str=ret + return status,status_str + diff --git a/examples/lab_devices/julaboF32HD.py b/examples/lab_devices/julaboF32HD.py new file mode 100644 index 000000000..f16c2162b --- /dev/null +++ b/examples/lab_devices/julaboF32HD.py @@ -0,0 +1,24 @@ +# +# ------------------------------------------------------------ +# Copyright (c) All rights reserved +# SiLab, Institute of Physics, University of Bonn +# ------------------------------------------------------------ +# + +''' Example how to use the tiller. +''' + +import time + +from basil.dut import Dut + +dut = Dut('julaboF32HD.yaml') +dev.init() +print "ID",dev["tiller"].get_identifier() +print "status",dev["tiller"].get_status() + +### start +### set menu->confiuration->setpoint->rs232 +dev["tiller"].start_thermostat() +dev["tiller"].get_status() + diff --git a/examples/lab_devices/julaboF32HD.yaml b/examples/lab_devices/julaboF32HD.yaml new file mode 100644 index 000000000..5b48673bb --- /dev/null +++ b/examples/lab_devices/julaboF32HD.yaml @@ -0,0 +1,19 @@ +transfer_layer: + - name : Serial + type : Serial + init : + port : /dev/ttyUSB5 + read_termination : "\r\n" + write_termination : "\r" + baudrate : 4800 + timeout : 2.0 + parity : "N" ### serial.PARITY_NONE + xonxoff : True ### software handshake on + rtscts : False + dsrdtr : False + + +hw_drivers: + - name : tiller + type : julaboF32HD + interface : Serial