Add a fake Huber bath
This commit is contained in:
219
site_ansto/instrument/TEST_SICS/fakeHuber/fakeHuber.py
Executable file
219
site_ansto/instrument/TEST_SICS/fakeHuber/fakeHuber.py
Executable file
@ -0,0 +1,219 @@
|
||||
#!/usr/bin/python
|
||||
# vim: ft=python ts=8 sts=4 sw=4 et autoindent smartindent nocindent
|
||||
# author: Douglas Clowes (douglas.clowes@ansto.gov.au) 2014
|
||||
#
|
||||
from twisted.internet import reactor, protocol
|
||||
from twisted.protocols.basic import LineReceiver
|
||||
from twisted.python import log
|
||||
from twisted.internet.task import LoopingCall
|
||||
|
||||
import os
|
||||
import sys
|
||||
import curses
|
||||
sys.path.insert(0, os.path.realpath(os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]),"../../util"))))
|
||||
from displayscreen import Screen
|
||||
|
||||
devices = []
|
||||
|
||||
def hexData(data):
|
||||
str = "%04X" % data
|
||||
return str
|
||||
|
||||
def hexTemp(temp):
|
||||
str = "%04X" % int(temp * 100)
|
||||
if len(str) > 4:
|
||||
str = str[-4:]
|
||||
return str
|
||||
|
||||
def binTemp(temp):
|
||||
x = binData(temp)
|
||||
x *= 0.01
|
||||
return x
|
||||
|
||||
def binData(data):
|
||||
x = int(data, 16)
|
||||
if x > 0x8000:
|
||||
x -= 0x10000
|
||||
return x
|
||||
|
||||
class Huber(LineReceiver):
|
||||
def __init__(self):
|
||||
self.delimiter = '\r\n'
|
||||
self.setpoint = 25.00
|
||||
self.internal = 25.00
|
||||
self.external = 24.00
|
||||
self.mode = 0
|
||||
self.control = 1
|
||||
self.min_set = 5.00
|
||||
self.max_set = 35.00
|
||||
self.data = {}
|
||||
self.set_data()
|
||||
|
||||
def set_data(self):
|
||||
self.data["00"] = hexTemp(self.setpoint)
|
||||
self.data["01"] = hexTemp(self.internal)
|
||||
self.data["07"] = hexTemp(self.external)
|
||||
self.data["13"] = hexData(self.mode)
|
||||
self.data["14"] = hexData(self.control)
|
||||
self.data["30"] = hexTemp(self.min_set)
|
||||
self.data["31"] = hexTemp(self.max_set)
|
||||
|
||||
def iterate(self):
|
||||
if self.mode == 0: # internal
|
||||
self.external = self.internal - 1.0
|
||||
if self.setpoint != self.internal:
|
||||
self.internal = self.setpoint * 0.9 + self.internal * 0.1
|
||||
else:
|
||||
self.internal = self.external + 1.0
|
||||
if self.setpoint != self.external:
|
||||
self.external = self.setpoint * 0.9 + self.external * 0.1
|
||||
self.set_data()
|
||||
|
||||
def write(self, data):
|
||||
sent = data + self.delimiter
|
||||
print "transmitted:", repr(sent)
|
||||
self.transport.write(sent)
|
||||
|
||||
def lineReceived(self, data):
|
||||
print "lineReceived:", data
|
||||
if len(data) >= 8 and data[0] == "{":
|
||||
m_field = data[1]
|
||||
t_field = data[2:4]
|
||||
v_field = data[4:]
|
||||
if t_field not in self.data:
|
||||
print "Unknown address in: '%s'" % data
|
||||
return
|
||||
if v_field == "****":
|
||||
self.write("{S" + t_field + self.data[t_field])
|
||||
return
|
||||
else:
|
||||
if t_field == "00":
|
||||
newTemp = binTemp(v_field)
|
||||
if self.min_set <= newTemp <= self.max_set:
|
||||
self.setpoint = newTemp
|
||||
if t_field == "13":
|
||||
self.mode = binData(v_field)
|
||||
if t_field == "14":
|
||||
self.control = binData(v_field)
|
||||
if t_field == "30":
|
||||
newTemp = binTemp(v_field)
|
||||
if -150 <= newTemp <= 350:
|
||||
self.min_set = newTemp
|
||||
if t_field == "31":
|
||||
newTemp = binTemp(v_field)
|
||||
if -150 <= newTemp <= 350:
|
||||
self.max_set = newTemp
|
||||
self.set_data()
|
||||
return
|
||||
print "Unimplemented command for: '%s'" % data
|
||||
return
|
||||
|
||||
def rawDataReceived(self, data):
|
||||
#print "rawDataReceived:", repr(data)
|
||||
self.transport.write(data)
|
||||
self.line += data
|
||||
if self.line.endswith(self.delimiter):
|
||||
self.line = self.line[:-len(self.delimiter)]
|
||||
self.lineReceived(self.line)
|
||||
self.line = ""
|
||||
|
||||
def connectionMade(self):
|
||||
print "connectionMade"
|
||||
devices.append(self)
|
||||
|
||||
def connectionLost(self, reason):
|
||||
print "connectionLost"
|
||||
devices.remove(self)
|
||||
|
||||
def device_iterator():
|
||||
global devices
|
||||
for dev in devices:
|
||||
dev.iterate()
|
||||
|
||||
def display_iterator():
|
||||
global screen, devices
|
||||
|
||||
try:
|
||||
rows, cols = screen.stdscr.getmaxyx()
|
||||
screen.stdscr.clear()
|
||||
col = 0
|
||||
base = 0
|
||||
screen.stdscr.addstr(base + 1, 0, "Setpoint: ")
|
||||
screen.stdscr.addstr(base + 2, 0, "Internal: ")
|
||||
screen.stdscr.addstr(base + 3, 0, "External: ")
|
||||
screen.stdscr.addstr(base + 4, 0, "Mode : ")
|
||||
screen.stdscr.addstr(base + 5, 0, "Control : ")
|
||||
screen.stdscr.addstr(base + 6, 0, "Min_Set : ")
|
||||
screen.stdscr.addstr(base + 7, 0, "Max_Set : ")
|
||||
for dev in devices:
|
||||
col += 1
|
||||
screen.stdscr.addstr(0, 12 * col, "Top TODO")
|
||||
try:
|
||||
screen.stdscr.addstr(base + 1, 12 * col, "%8.2f" % dev.setpoint)
|
||||
screen.stdscr.addstr(base + 2, 12 * col, "%8.2f" % dev.internal)
|
||||
screen.stdscr.addstr(base + 3, 12 * col, "%8.2f" % dev.external)
|
||||
screen.stdscr.addstr(base + 4, 12 * col, "%8d" % dev.mode)
|
||||
screen.stdscr.addstr(base + 5, 12 * col, "%8d" % dev.control)
|
||||
screen.stdscr.addstr(base + 6, 12 * col, "%8.2f" % dev.min_set)
|
||||
screen.stdscr.addstr(base + 7, 12 * col, "%8.2f" % dev.max_set)
|
||||
except:
|
||||
pass
|
||||
except:
|
||||
raise
|
||||
finally:
|
||||
try:
|
||||
screen.stdscr.refresh()
|
||||
except:
|
||||
pass
|
||||
|
||||
class MyScreen(Screen):
|
||||
def __init__(self, stdscr):
|
||||
Screen.__init__(self, stdscr)
|
||||
|
||||
def sendLine(self, txt):
|
||||
global devices
|
||||
|
||||
def write(self, txt):
|
||||
try:
|
||||
newLine = self.lines[-1] + " => " + txt
|
||||
del self.lines[-1]
|
||||
self.addLine(newLine)
|
||||
except:
|
||||
pass
|
||||
|
||||
def main():
|
||||
global screen
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(description="Fake Huber device")
|
||||
parser.add_argument('instrument', help='The instrument name', nargs='*')
|
||||
parser.add_argument('-p', '--port',\
|
||||
help='Port on which to listen',\
|
||||
type=int, default=61000)
|
||||
parser.add_argument('-v', '--verbose',\
|
||||
help='Print lots of stuff',\
|
||||
action='store_true', default=False)
|
||||
parser.add_argument('-w', '--window',\
|
||||
help='Create a display window',\
|
||||
action='store_true', default=False)
|
||||
args = parser.parse_args()
|
||||
log.startLogging(open(("/tmp/Fake_Huber.log"), "w"))
|
||||
if args.verbose:
|
||||
print "Args:", args
|
||||
Verbose = True
|
||||
|
||||
if (args.window):
|
||||
stdscr = curses.initscr()
|
||||
screen = MyScreen(stdscr)
|
||||
reactor.addReader(screen)
|
||||
disp_iter = LoopingCall(display_iterator)
|
||||
disp_iter.start(0.5)
|
||||
|
||||
dev_iter = LoopingCall(device_iterator)
|
||||
dev_iter.start(1.0)
|
||||
factory = protocol.ServerFactory()
|
||||
factory.protocol = Huber
|
||||
reactor.listenTCP(args.port, factory)
|
||||
reactor.run()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Reference in New Issue
Block a user