add sim-server again based on socketserver

- fix ls370test config file
+ fix issues with frappy_psi.ls370res
+ add frappy_psi.ls370sim

Change-Id: Ie61e3ea01c4b9c7c1286426504e50acf9413a8ba
Reviewed-on: https://forge.frm2.tum.de/review/c/secop/frappy/+/34957
Reviewed-by: Markus Zolliker <markus.zolliker@psi.ch>
Tested-by: Jenkins Automated Tests <pedersen+jenkins@frm2.tum.de>
This commit is contained in:
2024-11-14 11:42:29 +01:00
parent d618fafe4b
commit 17070ca732
3 changed files with 160 additions and 175 deletions

View File

@ -63,7 +63,12 @@ def parse_result(reply):
class LakeShoreIO(HasIO):
def set_param(self, cmd, *args):
head = ','.join([cmd] + [f'{a:g}' for a in args])
args = [f'{a:g}' for a in args]
if ' ' in cmd.strip():
args.insert(0, cmd)
else:
args[0] = cmd + args[0]
head = ','.join(args)
tail = cmd.replace(' ', '?')
reply = self.io.communicate(f'{head};{tail}')
return parse_result(reply)
@ -99,7 +104,7 @@ class Switcher(LakeShoreIO, ChannelSwitcher):
if channelno is None:
self.status = 'ERROR', 'no enabled channel'
return
self.set_param(f'SCAN {channelno},0')
self.set_param('SCAN ', channelno, 0)
def doPoll(self):
"""poll buttons
@ -160,7 +165,7 @@ class Switcher(LakeShoreIO, ChannelSwitcher):
self.measure_delay = chan.dwell
def set_active_channel(self, chan):
self.set_param(f'SCAN {chan.channel},0')
self.set_param('SCAN ', chan.channel, 0)
chan._last_range_change = time.monotonic()
self.set_delays(chan)
@ -227,7 +232,7 @@ class ResChannel(LakeShoreIO, Channel):
now = time.monotonic()
if now + 0.5 < max(self._last_range_change, self.switcher._start_switch) + self.pause:
return None
result = self.get_param(f'RDGR{self.channel}')
result = self.get_param(f'RDGR?{self.channel}')
if self.autorange:
self.fix_autorange()
if now + 0.5 > self._last_range_change + self.pause:
@ -251,7 +256,7 @@ class ResChannel(LakeShoreIO, Channel):
def read_value(self):
if self.channel == self.switcher.value == self.switcher.target:
value = self._read_value()
value = self.get_value()
if value is not None:
return value
return self.value # return previous value
@ -264,7 +269,7 @@ class ResChannel(LakeShoreIO, Channel):
@CommonReadHandler(rdgrng_params)
def read_rdgrng(self):
iscur, exc, rng, autorange, excoff = self.get_param(f'RDGRNG{self.channel}')
iscur, exc, rng, autorange, excoff = self.get_param(f'RDGRNG?{self.channel}')
self._prev_rdgrng = iscur, exc
if autorange: # pressed autorange button
if not self._toggle_autorange:
@ -293,8 +298,7 @@ class ResChannel(LakeShoreIO, Channel):
excoff = 1
rng = change['range']
if self.autorange:
if rng < self.minrange:
rng = self.minrange
rng = max(rng, self.minrange)
self.set_param(f'RDGRNG {self.channel}', iscur, exc, rng, 0, excoff)
self.read_range()

View File

@ -16,84 +16,38 @@
# Module authors:
# Markus Zolliker <markus.zolliker@psi.ch>
# *****************************************************************************
"""a very simple simulator for a LakeShore Model 370"""
"""a very simple simulator for LakeShore Models 370 and 372
reduced to the functionality actually used in e.g. frappy_psi.ls370res
"""
import time
from frappy.modules import Communicator
class Ls370Sim(Communicator):
CHANNEL_COMMANDS = [
('RDGR?%d', '1.0'),
('RDGST?%d', '0'),
('RDGRNG?%d', '0,5,5,0,0'),
('INSET?%d', '1,5,5,0,0'),
('FILTER?%d', '1,5,80'),
]
OTHER_COMMANDS = [
('*IDN?', 'LSCI,MODEL370,370184,05302003'),
('SCAN?', '3,1'),
('*OPC?', '1'),
]
def earlyInit(self):
super().earlyInit()
self._data = dict(self.OTHER_COMMANDS)
for fmt, v in self.CHANNEL_COMMANDS:
for chan in range(1,17):
self._data[fmt % chan] = v
def communicate(self, command):
self.comLog('> %s' % command)
# simulation part, time independent
for channel in range(1,17):
_, _, _, _, excoff = self._data['RDGRNG?%d' % channel].split(',')
if excoff == '1':
self._data['RDGST?%d' % channel] = '6'
else:
self._data['RDGST?%d' % channel] = '0'
chunks = command.split(';')
reply = []
for chunk in chunks:
if '?' in chunk:
reply.append(self._data[chunk])
else:
for nqarg in (1,0):
if nqarg == 0:
qcmd, arg = chunk.split(' ', 1)
qcmd += '?'
else:
qcmd, arg = chunk.split(',', nqarg)
qcmd = qcmd.replace(' ', '?', 1)
if qcmd in self._data:
self._data[qcmd] = arg
break
reply = ';'.join(reply)
self.comLog('< %s' % reply)
return reply
class Ls372Sim(Communicator):
class _Ls37xSim(Communicator):
# commands containing %d for the channel number
CHANNEL_COMMANDS = [
('RDGR?%d', '1.0'),
('RDGK?%d', '1.5'),
('RDGST?%d', '0'),
('RDGRNG?%d', '0,5,5,0,0'),
('INSET?%d', '1,5,5,0,0'),
('INSET?%d', '1,3,3,0,0'),
('FILTER?%d', '1,5,80'),
]
# commands not related to a channel
OTHER_COMMANDS = [
('*IDN?', 'LSCI,MODEL372,372184,05302003'),
('SCAN?', '3,1'),
('PID?1', '10,10,0'),
('*OPC?', '1'),
]
def earlyInit(self):
super().earlyInit()
self._res = {}
self._start = time.time()
self._data = dict(self.OTHER_COMMANDS)
for fmt, v in self.CHANNEL_COMMANDS:
for chan in range(1,17):
for chan in range(1, 17):
self._data[fmt % chan] = v
def communicate(self, command):
@ -105,6 +59,10 @@ class Ls372Sim(Communicator):
self._data['RDGST?%d' % channel] = '6'
else:
self._data['RDGST?%d' % channel] = '0'
channel = int(self._data['SCAN?'].split(',', 1)[0])
self._res[channel] = channel + (time.time() - self._start) / 3600
strvalue = f'{self._res[channel]:g}'
self._data['RDGR?%d' % channel] = self._data['RDGK?%d' % channel] = strvalue
chunks = command.split(';')
reply = []
@ -112,7 +70,7 @@ class Ls372Sim(Communicator):
if '?' in chunk:
reply.append(self._data[chunk])
else:
for nqarg in (1,0):
for nqarg in (1, 0):
if nqarg == 0:
qcmd, arg = chunk.split(' ', 1)
qcmd += '?'
@ -125,3 +83,16 @@ class Ls372Sim(Communicator):
reply = ';'.join(reply)
self.comLog('< %s' % reply)
return reply
class Ls370Sim(_Ls37xSim):
OTHER_COMMANDS = _Ls37xSim.OTHER_COMMANDS + [
('*IDN?', 'LSCI,MODEL370,370184,05302003'),
]
class Ls372Sim(_Ls37xSim):
OTHER_COMMANDS = _Ls37xSim.OTHER_COMMANDS + [
('*IDN?', 'LSCI,MODEL372,372184,05302003'),
('PID?1', '10,10,0'),
]