Merge branch 'wip' of https://gitea.psi.ch/linse/frappy into wip

This commit is contained in:
2025-07-04 14:33:03 +02:00
7 changed files with 68 additions and 56 deletions

View File

@@ -1,14 +1,12 @@
# by ID (independent of plug location) # by id (independent of plug location, but may not neccessarly be unique)
# to verify just do:
# ls /dev/serial/by-id
turbo_uri = '/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A601PCGF-if00-port0' turbo_uri = '/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A601PCGF-if00-port0'
press_uri = '/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AH07445U-if00-port0' press_uri = '/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AH07445U-if00-port0'
itc_uri = '/dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0' itc_uri = '/dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0'
lsc_uri = '192.168.1.2:7777' lsc_uri = '192.168.1.2:7777'
# by plug location: logo_ip = '192.168.0.3'
#turbo_uri='/dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.1:1.0-port0' # by plug location would also be possible (/dev/serial/by-path)
#press_uri = '/dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.2:1.0-port0'
#itc_uri = '/dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0-port0'
# over USB (does not work anymore)
#lsc_uri='serial:///dev/ttyACM1?baudrate=57600+parity=odd+bytesize=7+stopbits=1',
Node('dil5_logo.psi.ch', Node('dil5_logo.psi.ch',
@@ -20,7 +18,7 @@ Node('dil5_logo.psi.ch',
Mod('logo', Mod('logo',
'frappy_psi.logo.IO', 'frappy_psi.logo.IO',
'', '',
ip_address = "192.168.0.3", ip_address = logo_ip,
tcap_client = 0x3000, tcap_client = 0x3000,
tsap_server = 0x2000 tsap_server = 0x2000
) )
@@ -45,7 +43,7 @@ Mod('V4',
'frappy_psi.logo.DigitalActuator', 'frappy_psi.logo.DigitalActuator',
'compressor to dump', 'compressor to dump',
io = 'logo', io = 'logo',
# feedback_addr ="V1024.5", # not verified # feedback seems not to work
output_addr ="V1064.7", output_addr ="V1064.7",
target_addr ="V404.1", target_addr ="V404.1",
) )

View File

@@ -12,4 +12,4 @@
{"path": "node", "type": "text", "readonly": false, "cmd": "capslope node"}, {"path": "node", "type": "text", "readonly": false, "cmd": "capslope node"},
{"path": "unit", "type": "float", "readonly": false, "cmd": "capslope unit", "description": "unit=60: mainunits/minutes, unit=1: mainunits/sec"}, {"path": "unit", "type": "float", "readonly": false, "cmd": "capslope unit", "description": "unit=60: mainunits/minutes, unit=1: mainunits/sec"},
{"path": "ref", "type": "float", "readonly": false, "cmd": "capslope ref"}, {"path": "ref", "type": "float", "readonly": false, "cmd": "capslope ref"},
{"path": "buffersize", "type": "float", "readonly": false, "cmd": "capslope buffersize"}]}} {"path": "bufperiod", "type": "float", "readonly": false, "cmd": "capslope bufperiod"}]}}

View File

@@ -18,7 +18,7 @@
{"path": "heaterselect", "type": "enum", "enum": {"sample": 0, "mix": 1, "mix(temporarely)": 2}, "readonly": false, "cmd": "ts heaterselect"}, {"path": "heaterselect", "type": "enum", "enum": {"sample": 0, "mix": 1, "mix(temporarely)": 2}, "readonly": false, "cmd": "ts heaterselect"},
{"path": "control", "type": "enum", "enum": {"off": 0, "sample": 6, "mix": 5, "samplehtr": 8}, "readonly": false, "cmd": "ts control", "description": "click off to reload list"}, {"path": "control", "type": "enum", "enum": {"off": 0, "sample": 6, "mix": 5, "samplehtr": 8}, "readonly": false, "cmd": "ts control", "description": "click off to reload list"},
{"path": "heatermode", "type": "enum", "enum": {"disabled": -1, "off": 0, "on": 1}, "readonly": false, "cmd": "ts heatermode"}, {"path": "heatermode", "type": "enum", "enum": {"disabled": -1, "off": 0, "on": 1}, "readonly": false, "cmd": "ts heatermode"},
{"path": "heaterrange", "type": "enum", "enum": {"2uW": 1, "20uW": 2, "200uW": 3, "2mW": 4, "20mW": 5}, "readonly": false, "cmd": "ts heaterrange"}, {"path": "heaterrange", "type": "enum", "enum": {"off": 0, "2uW": 1, "20uW": 2, "200uW": 3, "2mW": 4, "20mW": 5}, "readonly": false, "cmd": "ts heaterrange"},
{"path": "autoheater", "type": "bool", "readonly": false, "cmd": "ts autoheater", "description": "automatic heater range", "kids": 12}, {"path": "autoheater", "type": "bool", "readonly": false, "cmd": "ts autoheater", "description": "automatic heater range", "kids": 12},
{"path": "autoheater/wlp0", "type": "float", "readonly": false, "cmd": "ts autoheater/wlp0", "description": "weak link base temperature (used for auto heater)"}, {"path": "autoheater/wlp0", "type": "float", "readonly": false, "cmd": "ts autoheater/wlp0", "description": "weak link base temperature (used for auto heater)"},
{"path": "autoheater/wlp1", "type": "float", "readonly": false, "cmd": "ts autoheater/wlp1", "description": "weak link temperature at 1 uW (used for auto heater)"}, {"path": "autoheater/wlp1", "type": "float", "readonly": false, "cmd": "ts autoheater/wlp1", "description": "weak link temperature at 1 uW (used for auto heater)"},

View File

@@ -18,7 +18,7 @@
{"path": "heaterselect", "type": "enum", "enum": {"sample": 0, "mix": 1, "mix(temporarely)": 2}, "readonly": false, "cmd": "ts heaterselect"}, {"path": "heaterselect", "type": "enum", "enum": {"sample": 0, "mix": 1, "mix(temporarely)": 2}, "readonly": false, "cmd": "ts heaterselect"},
{"path": "control", "type": "enum", "enum": {"off": 0, "sample": 6, "mix": 5, "samplehtr": 8}, "readonly": false, "cmd": "ts control", "description": "click off to reload list"}, {"path": "control", "type": "enum", "enum": {"off": 0, "sample": 6, "mix": 5, "samplehtr": 8}, "readonly": false, "cmd": "ts control", "description": "click off to reload list"},
{"path": "heatermode", "type": "enum", "enum": {"disabled": -1, "off": 0, "on": 1}, "readonly": false, "cmd": "ts heatermode"}, {"path": "heatermode", "type": "enum", "enum": {"disabled": -1, "off": 0, "on": 1}, "readonly": false, "cmd": "ts heatermode"},
{"path": "heaterrange", "type": "enum", "enum": {"2uW": 1, "20uW": 2, "200uW": 3, "2mW": 4, "20mW": 5}, "readonly": false, "cmd": "ts heaterrange"}, {"path": "heaterrange", "type": "enum", "enum": {"off": 0, "2uW": 1, "20uW": 2, "200uW": 3, "2mW": 4, "20mW": 5}, "readonly": false, "cmd": "ts heaterrange"},
{"path": "autoheater", "type": "bool", "readonly": false, "cmd": "ts autoheater", "description": "automatic heater range", "kids": 12}, {"path": "autoheater", "type": "bool", "readonly": false, "cmd": "ts autoheater", "description": "automatic heater range", "kids": 12},
{"path": "autoheater/wlp0", "type": "float", "readonly": false, "cmd": "ts autoheater/wlp0", "description": "weak link base temperature (used for auto heater)"}, {"path": "autoheater/wlp0", "type": "float", "readonly": false, "cmd": "ts autoheater/wlp0", "description": "weak link base temperature (used for auto heater)"},
{"path": "autoheater/wlp1", "type": "float", "readonly": false, "cmd": "ts autoheater/wlp1", "description": "weak link temperature at 1 uW (used for auto heater)"}, {"path": "autoheater/wlp1", "type": "float", "readonly": false, "cmd": "ts autoheater/wlp1", "description": "weak link temperature at 1 uW (used for auto heater)"},

View File

@@ -18,7 +18,7 @@
{"path": "heaterselect", "type": "enum", "enum": {"sample": 0, "mix": 1, "mix(temporarely)": 2}, "readonly": false, "cmd": "ts heaterselect"}, {"path": "heaterselect", "type": "enum", "enum": {"sample": 0, "mix": 1, "mix(temporarely)": 2}, "readonly": false, "cmd": "ts heaterselect"},
{"path": "control", "type": "enum", "enum": {"off": 0, "sample": 6, "mix": 5, "samplehtr": 8}, "readonly": false, "cmd": "ts control", "description": "click off to reload list"}, {"path": "control", "type": "enum", "enum": {"off": 0, "sample": 6, "mix": 5, "samplehtr": 8}, "readonly": false, "cmd": "ts control", "description": "click off to reload list"},
{"path": "heatermode", "type": "enum", "enum": {"disabled": -1, "off": 0, "on": 1}, "readonly": false, "cmd": "ts heatermode"}, {"path": "heatermode", "type": "enum", "enum": {"disabled": -1, "off": 0, "on": 1}, "readonly": false, "cmd": "ts heatermode"},
{"path": "heaterrange", "type": "enum", "enum": {"2uW": 1, "20uW": 2, "200uW": 3, "2mW": 4, "20mW": 5}, "readonly": false, "cmd": "ts heaterrange"}, {"path": "heaterrange", "type": "enum", "enum": {"off": 0, "2uW": 1, "20uW": 2, "200uW": 3, "2mW": 4, "20mW": 5}, "readonly": false, "cmd": "ts heaterrange"},
{"path": "autoheater", "type": "bool", "readonly": false, "cmd": "ts autoheater", "description": "automatic heater range", "kids": 12}, {"path": "autoheater", "type": "bool", "readonly": false, "cmd": "ts autoheater", "description": "automatic heater range", "kids": 12},
{"path": "autoheater/wlp0", "type": "float", "readonly": false, "cmd": "ts autoheater/wlp0", "description": "weak link base temperature (used for auto heater)"}, {"path": "autoheater/wlp0", "type": "float", "readonly": false, "cmd": "ts autoheater/wlp0", "description": "weak link base temperature (used for auto heater)"},
{"path": "autoheater/wlp1", "type": "float", "readonly": false, "cmd": "ts autoheater/wlp1", "description": "weak link temperature at 1 uW (used for auto heater)"}, {"path": "autoheater/wlp1", "type": "float", "readonly": false, "cmd": "ts autoheater/wlp1", "description": "weak link temperature at 1 uW (used for auto heater)"},

View File

@@ -24,29 +24,20 @@ from frappy.core import Parameter, Attached
class WrapControlledBy: class WrapControlledBy:
"""mixin for modules with controlled_by """mixin to add controlled_by to writable modules
Two use cases: Create a wrapper class inheriting from this mixin
to add controlled_by to a Writable module
1) on the implementation of a hardware module it is already known that Usage:
HasControlledBy is wanted. In this case, functionality to apply the
target to the hardware has to be implemented in method 'set_target'
class MyWritable(HasControlledBy, ...): class Enhanced(WrapControlledBy, BaseWritable):
pass
def set_target(self, target): # typically nothing else has to be implemented
"apply target to HW"
# no supercall needed!
# do not override write_target ! from a module with output (inheriting from HasOutput), the
method update_target must be called for internal updates
2) a hardware module is already available, and we extend it with the
controlled_by stuff
class Enhanced(HasControlledBy, BaseWritable):
set_target = BaseWritable.write_target
# nothing else is needed.
""" """
controlled_by = Parameter('source of target value', EnumType(members={'self': 0}), default=0) controlled_by = Parameter('source of target value', EnumType(members={'self': 0}), default=0)
@@ -87,12 +78,12 @@ class WrapControlledBy:
self.write_controlled_by('self') self.write_controlled_by('self')
def set_off(self): def set_off(self):
"""to be overriden if the off state should be different than the default """to be overridden if the off state should be different from the default
on a FloatRange() the default value is 0 on a FloatRange() the default value is 0
""" """
self.self_controlled() self.self_controlled()
self.set_target_cby(self.parameters['target'].datatype.default) self.internal_set_target(self.parameters['target'].datatype.default)
def update_target(self, module, value): def update_target(self, module, value):
"""update internal target value """update internal target value
@@ -108,28 +99,50 @@ class WrapControlledBy:
if deactivate_control: if deactivate_control:
deactivate_control(module) deactivate_control(module)
self.controlled_by = module self.controlled_by = module
target = self.set_target_cby(value) target = self.internal_set_target(value)
self.target = value if target is None else target self.target = value if target is None else target
def write_target(self, target): def write_target(self, target):
self.self_controlled() self.self_controlled()
return self.set_target_cby(target) return self.internal_set_target(target)
def set_target_cby(self, target): def internal_set_target(self, target):
# we need this additional indirection:
# super().write_target must refer to an inherited base class
# which is after WrapControlledBy in the method resolution order
return super().write_target(target) return super().write_target(target)
class HasControlledBy(WrapControlledBy): class HasControlledBy(WrapControlledBy):
"""mixin for controlled_by functionality
Create a wrapper class inheriting from this mixin
to add controlled_by to a Writable module
Usage:
class Enhanced(HasControlledBy, BaseWritable):
def set_target(self, value):
# implement here hardware access for setting target
# do not override write_target!
from a module with output (inheriting from HasOutput), the
method update_target must be called for internal updates
"""
def set_target(self, value): def set_target(self, value):
"""to be overridden for setting target of HW""" """to be overridden for setting target of HW"""
raise NotImplementedError raise NotImplementedError
def set_target_cby(self, value): def internal_set_target(self, value):
"""to be overridden in case this mixin is not added on top""" # we need this additional indirection:
# self.write_target must refer to a base class which
# is before HasControlledBy in the method resolution order
return self.set_target(value) return self.set_target(value)
class WrapOutputModule: class HasOutputModule:
"""mixin for modules having an output module """mixin for modules having an output module
this module will call the update_target method of an output module this module will call the update_target method of an output module
@@ -145,7 +158,14 @@ class WrapOutputModule:
self.output_module.register_input(self.name, self.deactivate_control) self.output_module.register_input(self.name, self.deactivate_control)
def write_control_active(self, value): def write_control_active(self, value):
"""override with supercall if needed""" """override with supercall if needed
control_active is readonly by default, as specified in the SECoP standard.
This method is meant to be called internally.
However, it is possible to override control_active with readonly=False
and this is quite useful IMHO in some situations
"""
out = self.output_module out = self.output_module
if out: if out:
if value: if value:
@@ -157,13 +177,16 @@ class WrapOutputModule:
out.set_off() # this sets out.controlled_by to 0 (=self) out.set_off() # this sets out.controlled_by to 0 (=self)
def set_control_active(self, active): def set_control_active(self, active):
"""to be overridden for switching hw control""" """to be overridden for switching hw control
TODO: remove this legacy method (replaced by write_control_active)
"""
self.control_active = active self.control_active = active
def activate_control(self): def activate_control(self):
"""method to switch control_active on """method to switch control_active on
to be called from the write_target method, with the target as argument TODO: remove this legacy method (replaced by write_control_active)
""" """
self.write_control_active(True) self.write_control_active(True)
@@ -178,16 +201,8 @@ class WrapOutputModule:
def write_target(self, target): def write_target(self, target):
self.write_control_active(True) self.write_control_active(True)
return self.set_target_out(target)
def set_target_out(self, target):
return super().write_target(target)
class HasOutputModule(WrapOutputModule):
def set_target(self, target):
"""to be overridden except for WrapOutputModule"""
raise NotImplementedError
def set_target_out(self, target):
return self.set_target(target) return self.set_target(target)
def set_target(self, target):
"""to be overridden"""
raise NotImplementedError

View File

@@ -126,8 +126,7 @@ class SeaClient(ProxyClient, Module):
_last_connect = 0 _last_connect = 0
def __init__(self, name, log, opts, srv): def __init__(self, name, log, opts, srv):
nodename = srv.node_cfg.get('name') or srv.node_cfg.get('equipment_id') instance = srv.secnode.name.rsplit('_', 1)[0]
instance = nodename.rsplit('_', 1)[0]
if 'uri' not in opts: if 'uri' not in opts:
self._instance = instance self._instance = instance
port = get_sea_port(instance) port = get_sea_port(instance)