diff --git a/cfg/dummy_cfg.py b/cfg/dummy_cfg.py new file mode 100644 index 0000000..bc8e86b --- /dev/null +++ b/cfg/dummy_cfg.py @@ -0,0 +1,98 @@ +Node('test.config.frappy.demo', + '''short description of the testing sec-node + +This description for the node can be as long as you need if you use a multiline string. + +Very long! +The needed fields are Equipment id (1st argument), description (this) + and the main interface of the node (3rd arg) +''', + 'tcp://10768', +) + +Mod('attachtest', + 'frappy_demo.test.WithAtt', + 'test attached', + att = 'LN2', +) + +Mod('pinata', + 'frappy_demo.test.Pin', + 'scan test', +) + +Mod('recursive', + 'frappy_demo.test.RecPin', + 'scan test', +) + +Mod('LN2', + 'frappy_demo.test.LN2', + 'random value between 0..100%', + value = Param(default = 0, unit = '%'), +) + +Mod('heater', + 'frappy_demo.test.Heater', + 'some heater', + maxheaterpower = 10, +) + +Mod('T1', + 'frappy_demo.test.Temp', + 'some temperature', + sensor = 'X34598T7', +) + +Mod('T2', + 'frappy_demo.test.Temp', + 'some temperature', + sensor = 'X34598T8', +) + +Mod('T3', + 'frappy_demo.test.Temp', + 'some temperature', + sensor = 'X34598T9', +) + +Mod('Lower', + 'frappy_demo.test.Lower', + 'something else', +) + +Mod('Decision', + 'frappy_demo.test.Mapped', + 'Random value from configured property choices. Config accepts anything ' \ + 'that can be converted to a list', + choices = ['Yes', 'Maybe', 'No'], +) + +Mod('c', + 'frappy_demo.test.Commands', + 'a command test', +) + +Mod('cryo', + 'frappy_demo.cryo.Cryostat', + 'A simulated cc cryostat with heat-load, specific heat for the sample and a ' + 'temperature dependent heat-link between sample and regulation.', + group='very important/stuff', + jitter=0.1, + T_start=10.0, + target=10.0, + looptime=1, + ramp=6, + maxpower=20.0, + heater=4.1, + mode='pid', + tolerance=0.1, + window=30, + timeout=900, + p = Param(40, unit='%/K'), # in case 'default' is the first arg, we can omit 'default=' + i = 10, + d = 2, + pid = Group('p', 'i', 'd'), + pollinterval = Param(export=False), + value = Param(unit = 'K', test = 'customized value'), +) diff --git a/frappy/client/__init__.py b/frappy/client/__init__.py index 4b03fe0..2f9d418 100644 --- a/frappy/client/__init__.py +++ b/frappy/client/__init__.py @@ -753,6 +753,25 @@ class SecopClient(ProxyClient): data = datatype.import_value(data) return data, qualifiers + def execCommandFromString(self, module, command, formatted_argument): + """call command from string argument + + return formatted data and qualifiers + """ + self.connect() + datatype = self.modules[module]['commands'][command]['datatype'].argument + if datatype: + argument = datatype.from_string(formatted_argument) + else: + if formatted_argument: + raise WrongTypeError('command has no argument') + argument = None + data, qualifiers = self.request(COMMANDREQUEST, self.identifier[module, command], argument)[2] + datatype = self.modules[module]['commands'][command]['datatype'].result + if datatype: + data = datatype.format_value(data) + return data, qualifiers + def updateValue(self, module, param, value, timestamp, readerror): datatype = self.modules[module]['parameters'][param]['datatype'] if readerror: diff --git a/frappy_demo/test.py b/frappy_demo/test.py index a86c777..218de41 100644 --- a/frappy_demo/test.py +++ b/frappy_demo/test.py @@ -22,11 +22,13 @@ import random -from frappy.datatypes import FloatRange, StringType, ValueType, TupleOf, StructOf, ArrayOf +from frappy.datatypes import FloatRange, StringType, ValueType, TupleOf, StructOf, ArrayOf, StatusType, BoolType from frappy.modules import Communicator, Drivable, Parameter, Property, Readable, Module, Attached from frappy.params import Command from frappy.dynamic import Pinata from frappy.errors import RangeError, HardwareError +from frappy.core import IDLE, WARN, ERROR, DISABLED + class Pin(Pinata): def scanModules(self): @@ -105,13 +107,27 @@ class Temp(Drivable): readonly=False, unit='K', ) + enabled = Parameter('enable', BoolType(), default=True, readonly=False) + status = Parameter(datatype=StatusType(Readable, 'DISABLED')) + _status = IDLE, '' def read_value(self): - return round(100 * random.random(), 1) + value = round(100 * random.random(), 1) + if value > 75: + self._status = ERROR, 'sensor break' + elif value > 50: + self._status = WARN, 'out of calibrated range' + else: + self._status = IDLE, '' + self.read_status() + return value def write_target(self, target): pass + def read_status(self): + return self._status if self.enabled else (DISABLED, 'disabled') + class Lower(Communicator): """Communicator returning a lowercase version of the request"""