Files
ilt1000/ilt1000.py

207 lines
5.1 KiB
Python
Raw Normal View History

2016-04-07 22:19:40 -07:00
#!/usr/bin/python3
import datetime
import serial
import time
2016-04-07 22:19:40 -07:00
class Error(Exception):
pass
class UnsupportedCommand(Error):
pass
class RequiredValueNotSet(Error):
pass
class OutOfRange(Error):
pass
class Saturated(Error):
pass
2016-04-08 10:59:37 -07:00
# TODO commands:
# eraselogdata
# getlogdata
# setautaveraging
# setcurrentloop
# sethiaveraging
# setlowaveraging
# setmedaveraging
# setsimpleirrcal
# setuserdark
# startlogdata
# stoplogdata
# usecalfactor
# usefeedbackres
# erasecalfactor
# getcalfactor
# setcalfactor
# setsamplecount
2016-04-07 22:19:40 -07:00
class ILT1000(object):
2016-04-08 11:24:02 -07:00
DARK_NONE = 0
DARK_FACTORY = 1
DARK_USER = 2
DARK_NAMES = {
0: 'None',
1: 'Factory',
2: 'User',
}
2016-04-08 10:59:37 -07:00
# ILT1000 presents two FTDI serial devices, which become ttyUSB0 and ttyUSB1
# if nothing else is attached. ttyUSB0 seems to be completely non-responsive.
# We default to ttyUSB1
def __init__(self, device='/dev/ttyUSB1', set_time=True):
self._dev = serial.Serial(device, baudrate=115200)
self._Clear()
2016-04-07 22:19:40 -07:00
assert int(self._SendCommand('echooff')) == 0
if set_time:
self.SetDateTime()
def _Clear(self):
self._dev.timeout = 0.1
self._dev.write(b'\r\n')
self._dev.read(128)
self._dev.timeout = None
2016-04-07 22:19:40 -07:00
def _SendCommand(self, command):
self._dev.write(command.encode('ascii') + b'\r\n')
ret = self._dev.readline().rstrip().decode('ascii')
if ret == '-999':
raise UnsupportedCommand(command)
if ret == '-500':
raise RequiredValueNotSet(command)
if ret == '-501':
raise OutOfRange(command)
if ret == '-502':
raise Saturated(command)
return ret
def GetModelName(self):
return self._SendCommand('getmodelname')
def GetGeneration(self):
return int(self._SendCommand('getgeneration'))
def GetFirmwareVersion(self):
return self._SendCommand('getfwversion')
def GetSerialNumber(self):
return self._SendCommand('getserialnumber')
2016-04-08 11:17:43 -07:00
def GetAuxSerialNumber(self):
return self._SendCommand('getauxserialno')
def SetAuxSerialNumber(self, serial):
# SPEC ERROR
# This is undocumented.
assert int(self._SendCommand('setauxserialno %s' % serial)) == 0
2016-04-07 22:19:40 -07:00
def GetControllerTempF(self):
return int(self._SendCommand('gettemp'))
def GetAmbientTempF(self):
2016-04-08 10:59:37 -07:00
# SPEC ERROR
2016-04-07 22:19:40 -07:00
# Protocol doc indicates that this is degrees F * 100, but actual values
# look like just degrees F
return int(self._SendCommand('getambienttemp'))
def GetDateTime(self):
ret = self._SendCommand('getdatetime')
return datetime.datetime.fromtimestamp(int(ret.split()[2]))
def SetDateTime(self, now=None):
now = now or datetime.datetime.utcnow()
timestr = now.strftime('%m/%d/%Y %H:%M:%S')
ret = self._SendCommand('setdatetime ' + timestr)
assert int(ret) == 0
2016-04-08 10:59:37 -07:00
def GetSensorCurrent(self):
# SPEC ERROR
2016-04-08 11:11:34 -07:00
# Protocol doc indicates that this is in pA, but actual values are in
2016-04-08 10:59:37 -07:00
# scientific notation and appear to be A. They are also suspiciously
# similar to getvoltage return values.
2016-04-07 22:19:40 -07:00
ret = self._SendCommand('getcurrent')
return float(ret)
2016-04-08 10:59:37 -07:00
def GetSensorVoltage(self):
2016-04-07 22:19:40 -07:00
ret = self._SendCommand('getvoltage')
return float(ret) / 1000000
def GetTransmissionPercent(self):
ret = self._SendCommand('gettrans')
return float(ret) / 10
def GetOpticalDensity(self):
ret = self._SendCommand('getod')
return float(ret) / 100
2016-04-08 11:09:38 -07:00
def Get100PercentVoltage(self):
2016-04-08 11:11:34 -07:00
# SPEC ERROR
# Spec says microvolts, but actual values appear to be in volts.
2016-04-08 11:09:38 -07:00
ret = self._SendCommand('get100perc')
2016-04-08 11:11:34 -07:00
return float(ret)
2016-04-08 11:24:02 -07:00
2016-04-08 12:56:58 -07:00
def Set100PercentVoltage(self):
# SPEC ERROR
# Spec says microvolts, but actual values appear to be in volts.
ret = self._SendCommand('set100perc')
return float(ret)
2016-04-08 11:24:02 -07:00
def GetDarkMode(self):
return int(self._SendCommand('getdarkmode'))
2016-04-08 11:28:52 -07:00
2016-04-08 12:51:14 -07:00
_DARK_MODE_COMMANDS = {
DARK_NONE: 'usenodark',
DARK_FACTORY: 'usefactorydark',
DARK_USER: 'useuserdark',
}
def SetDarkMode(self, mode):
assert int(self._SendCommand(self._DARK_MODE_COMMANDS[mode])) == 0
2016-04-08 12:46:22 -07:00
def GetFactoryDarkVoltages(self):
# SPEC ERROR
# Actual return value sample:
# R1 12149 9733 9251 R2 12476 10080 9604 R3 13940 11894 11435
ret = self._SendCommand('getfactorydark')
return [float(x) / 1000000 for x in ret.split()]
2016-04-08 12:51:14 -07:00
def GetUserDarkVoltages(self):
# SPEC ERROR
# Actual return value sample:
# R1 12149 9733 9251 R2 12476 10080 9604 R3 13940 11894 11435
ret = self._SendCommand('getfactorydark')
return [float(x) / 1000000 for x in ret.split()]
2016-04-08 11:28:52 -07:00
def GetIrradiance(self):
ret = self._SendCommand('getirradiance')
return float(ret) / 1000
2016-04-08 11:42:37 -07:00
def GetClockFrequencyHz(self):
ret = self._SendCommand('getclockfreq')
return float(ret) / 100
def SetClockFrequency(self):
# SPEC ERROR
# Command returns -999 on my ILT1000-V02. Implementation below is untested
# and likely wrong.
assert int(self._SendCommand('setclockfreq')) == 0
self._dev.write(b'A')
time.sleep(60.0)
self._dev.write(b'B')
2016-04-08 12:25:02 -07:00
def GetFeedbackResistanceOhm(self):
ret = self._SendCommand('getfeedbackres')
return float(ret) * 100