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:
@ -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:
|
||||
|
Reference in New Issue
Block a user