frappy_psi.furnace: special classes PTXgauge and PRtransmitter

move some initialization from cfg file to source code
+ make 'out of calibrated range' and 'sensor break' more generic

Change-Id: I3e92100fdb9c983f82665de9d8e063609cd7af5a
This commit is contained in:
zolliker 2025-04-23 08:28:08 +02:00
parent e0bd84cc3b
commit d681507f94
3 changed files with 62 additions and 26 deletions

View File

@ -4,18 +4,18 @@ Node('fi.psi.ch',
)
Mod('T_main',
'frappy_psi.ionopimax.CurrentInput',
'frappy_psi.furnace.PRtransmitter',
'sample temperature',
addr='ai1',
valuerange=(0, 1372),
valuerange=(0, 2300),
value=Param(unit='degC'),
)
Mod('T_extra',
'frappy_psi.ionopimax.CurrentInput',
'frappy_psi.furnace.PRtransmitter',
'extra temperature',
addr='ai2',
valuerange=(0, 1372),
valuerange=(0, 2300),
value=Param(unit='degC'),
)
@ -28,6 +28,22 @@ Mod('T_wall',
value=Param(unit='degC'),
)
Mod('T3',
'frappy_psi.furnace.PRtransmitter',
'extra temperature',
addr='ai3',
valuerange=(0, 1372),
value=Param(unit='degC'),
)
Mod('T4',
'frappy_psi.furnace.PRtransmitter',
'extra temperature',
addr='ai4',
valuerange=(0, 1372),
value=Param(unit='degC'),
)
Mod('T',
'frappy_psi.picontrol.PI',
'controlled Temperature',
@ -77,7 +93,7 @@ Mod('flowswitch',
# )
Mod('p',
'frappy_psi.ionopimax.LogVoltageInput',
'frappy_psi.furnace.PKRgauge',
'pressure reading',
addr = 'av1',
rawrange = (1.82, 8.6),
@ -89,5 +105,5 @@ Mod('vso',
'frappy_psi.ionopimax.VoltagePower',
'voltage power output',
target = 24,
export = False,
# export = False,
)

View File

@ -25,6 +25,7 @@ from frappy.core import Module, Writable, Attached, Parameter, FloatRange, Reada
from frappy.mixins import HasControlledBy
from frappy_psi.picontrol import PImixin
from frappy_psi.convergence import HasConvergence
from frappy_psi.ionopimax import CurrentInput, LogVoltageInput
import frappy_psi.tdkpower as tdkpower
import frappy_psi.bkpower as bkpower
@ -99,3 +100,14 @@ class TdkOutput(HasControlledBy, tdkpower.Output):
class BkOutput(HasControlledBy, bkpower.Output):
pass
class PRtransmitter(CurrentInput):
rawrange = (0.004, 0.02)
extendedrange = (0.0036, 0.021)
class PKRgauge(LogVoltageInput):
rawrange = (1.82, 8.6)
valuerange = (5e-9, 1000)
extendedrange = (0.5, 9.5)

View File

@ -23,21 +23,22 @@
supports also the smaller model iono pi
"""
from pathlib import Path
from frappy.core import Readable, Writable, Parameter, BoolType, StringType,\
EnumType, FloatRange, Property, TupleOf, ERROR, IDLE
from frappy.errors import ConfigError, OutOfRangeError, ProgrammingError
from math import log
from pathlib import Path
from frappy.core import Readable, Writable, Parameter, Property, ERROR, IDLE, WARN
from frappy.errors import ConfigError, OutOfRangeError, ProgrammingError
from frappy.datatypes import BoolType, EnumType, FloatRange, NoneOr, StringType, TupleOf
class Base:
addr = Property('address', StringType())
_devpath = None
_devclass = None
_status = None
_status = IDLE, ''
def initModule(self):
super().initModule()
self.log.info('initModule %r', self.name)
candidates = list(Path('/sys/class').glob(f'ionopi*/*/{self.addr}'))
if not candidates:
raise ConfigError(f'can not find path for {self.addr}')
@ -59,10 +60,9 @@ class Base:
f.write(value)
def read_status(self):
if self._status is None:
return IDLE, ''
return self._status
class DigitalInput(Base, Readable):
value = Parameter('input state', BoolType())
true_level = Property('level representing True', EnumType(low=0, high=1), default=1)
@ -82,8 +82,7 @@ class DigitalOutput(DigitalInput, Writable):
def read_value(self):
reply = self.read(self.addr)
try:
self._status = None
self.read_status()
self._status = IDLE, ''
value = int(reply)
except ValueError:
if reply == 'S':
@ -95,6 +94,7 @@ class DigitalOutput(DigitalInput, Writable):
else:
self._status = ERROR, 'fault while open'
value = 1
self.read_status()
return value == self.true_level
def write_target(self, value):
@ -105,13 +105,25 @@ class AnalogInput(Base, Readable):
value = Parameter('analog value', FloatRange())
rawrange = Property('raw range (electronic)', TupleOf(FloatRange(),FloatRange()))
valuerange = Property('value range (physical)', TupleOf(FloatRange(),FloatRange()))
extendedrange = Property('range indicating "out of range", but not seansor fault',
NoneOr(TupleOf(FloatRange(), FloatRange())), default=None)
def read_value(self):
x0, x1 = self.rawrange
y0, y1 = self.valuerange
self.x = self.read(self.addr, self.scale)
self.read_status()
if self.status[0] == ERROR:
raise OutOfRangeError('sensor fault')
return y0 + (y1 - y0) * (self.x - x0) / (x1 - x0)
def read_status(self):
if self.rawrange[0] <= self.x <= self.rawrange[1]:
return IDLE, ''
if self.extendedrange is None or self.extendedrange[0] <= self.x <= self.extendedrange[1]:
return WARN, 'out of range'
return ERROR, 'sensor fault'
class VoltageInput(AnalogInput):
scale = 1e5
@ -127,25 +139,20 @@ class LogVoltageInput(VoltageInput):
x0, x1 = self.rawrange
y0, y1 = self.valuerange
self.x = self.read(self.addr, self.scale)
a = (x1-x0)/log(y1/y0,10)
self.read_status()
if self.status[0] == ERROR:
raise OutOfRangeError('sensor fault')
a = (x1-x0)/log(y1/y0, 10)
return 10**((self.x-x1)/a)*y1
class CurrentInput(AnalogInput):
scale = 1e6
rawrange = (0.004,0.02)
rawrange = (0.004, 0.02)
def initModule(self):
super().initModule()
self.write(f'{self.addr}_mode','U')
def read_value(self):
result = super().read_value()
if self.x > 0.021:
self.status = ERROR, 'sensor fault'
raise OutOfRangeError('sensor fault')
self.status = IDLE, ''
return result
self.write(f'{self.addr}_mode', 'U')
class AnalogOutput(AnalogInput, Writable):
@ -175,6 +182,7 @@ class VoltagePower(Base, Writable):
def write_target(self, value):
if value:
self.log.info('write vso %r', value)
self.write(self.addr, value, 1000)
self.write(f'{self.addr}_enabled', 1)
else: