From bca92d0ff76a44b826306770726d40026ca2a9e7 Mon Sep 17 00:00:00 2001 From: Sven Augustin Date: Sat, 13 Feb 2021 12:17:07 +0000 Subject: [PATCH] separate PVInfo from serve code --- morioc/morioc.py | 100 ++++++----------------------------------------- morioc/pvinfo.py | 90 ++++++++++++++++++++++++++++++++++++++++++ morioc/utils.py | 5 --- 3 files changed, 101 insertions(+), 94 deletions(-) create mode 100644 morioc/pvinfo.py delete mode 100644 morioc/utils.py diff --git a/morioc/morioc.py b/morioc/morioc.py index 5549432..2e9d177 100644 --- a/morioc/morioc.py +++ b/morioc/morioc.py @@ -2,10 +2,10 @@ from time import sleep from datetime import datetime from threading import Thread from pcaspy import SimpleServer, Driver -from pcaspy.driver import manager, _ait_d as AIT_D +from pcaspy.driver import manager from context import Context -from utils import typename +from pvinfo import make_pvinfos, make_pvdb, make_values INITIAL_PVDB = { #TODO make wait_time caput-able @@ -14,15 +14,6 @@ INITIAL_PVDB = { #TODO make wait_time caput-able } } -D_AIT = {v:k for k, v in AIT_D.items()} - -#PV data type: enum, string, char, float or int -DTYPES = { - str: "string", - float: "float", - int: "int" -} - class DefaultDriver(Driver): #TODO: caget on START_TIME crashes without this subclass?! @@ -49,6 +40,7 @@ class MorIOC(Context): self.driver.setParam("START_TIME", str(now)) self.driver.updatePVs() + self.running = False self.thread = Thread(target=self.run, daemon=True) self.thread.start() @@ -65,14 +57,16 @@ class MorIOC(Context): def serve(self, **kwargs): - ts, vs = make_mappings(kwargs, parse_string=False) - pvdb = make_pvdb(ts) + pvis = make_pvinfos(kwargs, parse_string=False) + pvdb = make_pvdb(pvis) self.createPV(pvdb) - self.setParams(**vs) + pvvs = make_values(pvis) + self.setParams(**pvvs) + def host(self, **kwargs): - ts, _vs = make_mappings(kwargs, parse_string=True) - pvdb = make_pvdb(ts) + pvis = make_pvinfos(kwargs, parse_string=True) + pvdb = make_pvdb(pvis) self.createPV(pvdb) @@ -81,7 +75,7 @@ class MorIOC(Context): return print("new PVs", pvdb) current_pvdb = self.driver.pvDB #TODO crash due to keyerror otherwise - self.server.createPV(self.prefix, pvdb) + self.server.createPV(self.prefix, pvdb) #TODO if pv name already contains ":", don't prepend self.prefix?! self.driver = self.DriverClass() self.driver.pvDB.update(current_pvdb) @@ -111,75 +105,3 @@ class MorIOC(Context): -def make_mappings(name_to_dtype_or_value, *args, **kwargs): - name_to_dtype = {} - name_to_value = {} - - for name, type_or_value in name_to_dtype_or_value.items(): - name = name.upper() - dtype, value = infer_type(type_or_value, *args, **kwargs) - - name_to_dtype[name] = dtype - name_to_value[name] = value - - return name_to_dtype, name_to_value - - -def infer_type(value, parse_string=True): #TODO arrays? strings? - # str -> "string", "" - # "test" -> "string", "test" - - #TODO parse_string, when? - # "string" -> "string", "" - # "float" -> "float", 0.0 - # or - # "string" -> "string", "string" - # "float" -> "string", "float" - - if isinstance(value, type): - dtype = value - value = dtype() - else: - dtype = type(value) - - if parse_string and isinstance(value, str): - if value in DTYPES.values(): - dtype = value - value = "" - - if not isinstance(dtype, str): - dtype = DTYPES.get(dtype, "string") #TODO default? - - return dtype, value - - -def make_pvdb(name_to_dtype): - pvdb = {} - for name, dtype in name_to_dtype.items(): - if not pv_is_managed(name): - print("will create", name) - pvdb[name] = {"type": dtype} - else: - pv_type = get_managed_pv_type(name) - if pv_type != dtype: - print(f"type for {name} changed:", pv_type, "->", dtype) #TODO what should be done if this happens? -# self.deletePV(name) -# pvdb[name] = {"type": dtype} - return pvdb - - -def pv_is_managed(name): - managed_pvs = manager.pvs["default"] - return name in managed_pvs - -def get_managed_pv_type(name): - managed_pvs = manager.pvs["default"] - pv = managed_pvs[name] - pv_type = pv.info.type - return D_AIT[pv_type] - - - -#TODO: -# - if pv name already contains ":", don't prepend prefix?! - diff --git a/morioc/pvinfo.py b/morioc/pvinfo.py new file mode 100644 index 0000000..493b5b4 --- /dev/null +++ b/morioc/pvinfo.py @@ -0,0 +1,90 @@ +from pcaspy.driver import manager, _ait_d as AIT_D + + +D_AIT = {v:k for k, v in AIT_D.items()} + +#PV data type: enum, string, char, float or int +DTYPES = { + str: "string", + float: "float", + int: "int" +} + + + +def make_values(pvinfos): + return {pvi.name: pvi.value for pvi in pvinfos} + + +def make_pvinfos(kwargs, parse_string=True): + return [PVInfo(*args, parse_string=parse_string) for args in kwargs.items()] + + + +class PVInfo: + + def __init__(self, name, data, parse_string=True): + self.name = name.upper() + self.dtype, self.value = infer_type(data, parse_string=parse_string) + + + +def infer_type(value, parse_string=True): #TODO arrays? strings? + # str -> "string", "" + # "test" -> "string", "test" + + #TODO parse_string, when? + # "string" -> "string", "" + # "float" -> "float", 0.0 + # or + # "string" -> "string", "string" + # "float" -> "string", "float" + + if isinstance(value, type): + dtype = value + value = dtype() + else: + dtype = type(value) + + if parse_string and isinstance(value, str): + if value in DTYPES.values(): + dtype = value + value = "" + + if not isinstance(dtype, str): + dtype = DTYPES.get(dtype, "string") #TODO default? + + return dtype, value + + + +def make_pvdb(pvinfos): + pvdb = {} + for pvi in pvinfos: + name, dtype = pvi.name, pvi.dtype + + if not pv_is_managed(name): + print("will create", name) + pvdb[name] = {"type": dtype} + else: + pv_type = get_managed_pv_type(name) + if pv_type != dtype: + print(f"type for {name} changed:", pv_type, "->", dtype) #TODO what should be done if this happens? +# self.deletePV(name) +# pvdb[name] = {"type": dtype} + + return pvdb + + +def pv_is_managed(name): + managed_pvs = manager.pvs["default"] + return name in managed_pvs + +def get_managed_pv_type(name): + managed_pvs = manager.pvs["default"] + pv = managed_pvs[name] + pv_type = pv.info.type + return D_AIT[pv_type] + + + diff --git a/morioc/utils.py b/morioc/utils.py deleted file mode 100644 index c3d4936..0000000 --- a/morioc/utils.py +++ /dev/null @@ -1,5 +0,0 @@ - -def typename(obj): - return type(obj).__name__ - -