1"""
2The classes Limits and LimitDefinition represent the contents
3of the SRDB limits tables OCF and OCP.
4"""
5
6import logging
7
8OCF_COLUMN_COUNT = 5
9OCP_COLUMN_COUNT = 6
10logger = logging.getLogger()
11
12
13class Limits:
14 """
15 Representation of a 'monitoring parameter checks' table (OCF) entry.
16
17 Raises:
18 ValueError: On incorrect number of OCF/OCP list entries.
19 """
20
21 def __init__(self, ocf_entry, ocp_entries=None):
22 """ Initializes Limits with an OCF entry as a list
23 and optionally multiple OCP entries as nested lists ordered by OCP_POS.
24 :param ocf_entry: [OCF_NAME, OCF_NBCHCK, OCF_NBOOL, OCF_INTER, OCF_CODIN]
25 :param ocp_entries: [[OCP_NAME, OCP_POS, OCP_TYPE, OCP_LVALU, OCP_HVALU, OCP_RLCHK, OCP_VALPAR], ...]
26 """
27 if len(ocf_entry) != OCF_COLUMN_COUNT:
28 raise ValueError(f"The OCP entry doesn't contain {OCF_COLUMN_COUNT} expected columns.")
29
30 self.name = ocf_entry[0]
31 self.nbchck = int(ocf_entry[1])
32 self.nbool = int(ocf_entry[2])
33 self.inter = ocf_entry[3]
34 self.codin = ocf_entry[4]
35 self.ocp = []
36
37 if ocp_entries:
38 if self.nbool != len(ocp_entries):
39 logger.warning(f"The number of OCP entries ({len(ocp_entries)}) of '{self.name}' "
40 f"doesn't match the NBOOL value ({self.nbool}).")
41
42 for ocp_entry in ocp_entries:
43 self.ocp.append(LimitDefinition(ocp_entry, self.codin))
44 self.ocp.sort(key=lambda entry: entry.pos)
45
46 def __repr__(self):
47 return f"Limits([{self.name}, {self.nbchck}, {self.nbool}, {self.inter}, {self.codin}])"
48
49
50class LimitDefinition:
51 """
52 Representation of a monitoring checks definition table (OCP) entry.
53
54 Raises:
55 ValueError: On incorrect number of OCP list entries.
56 """
57
58 def __init__(self, ocp_entry, codin):
59 """
60 Initializes a LimitDefinition with an OCP entry as a list
61 and a value interpretation field OCF_CODIN.
62 :param ocp_entry: [OCP_POS, OCP_TYPE, OCP_LVALU, OCP_HVALU, OCP_RLCHK, OCP_VALPAR]
63 :param codin: The interpretation of LVALU/HVALU: (I)nt, (R)eal or (A)SCII
64 """
65 if len(ocp_entry) != OCP_COLUMN_COUNT:
66 raise ValueError(f"The OCP entry doesn't contain {OCP_COLUMN_COUNT} expected columns.")
67
68 self.pos = int(ocp_entry[0])
69 self.type = ocp_entry[1]
70 self.rlchk = ocp_entry[4]
71 # Validity check is optional, rlchk parameter might be empty
72 if self.rlchk != '':
73 self.valpar = int(ocp_entry[5])
74 else:
75 self.valpar = None
76 self._set_limit_values(codin, ocp_entry[2], ocp_entry[3])
77
78 def _set_limit_values(self, codin, lvalu, hvalu):
79 """ Set high/low limit values and types according to the type interpretation OCF_CODIN. """
80 if codin == 'I':
81 self.lvalu = int(lvalu) if lvalu else lvalu
82 self.hvalu = int(hvalu) if hvalu else hvalu
83 elif codin == 'R':
84 self.lvalu = float(lvalu) if lvalu else lvalu
85 self.hvalu = float(hvalu) if hvalu else hvalu
86 else:
87 self.lvalu = lvalu
88 self.hvalu = hvalu
89
90 def __repr__(self):
91 return f"LimitDefinition([{self.pos}, {self.type}, " \
92 f"{self.lvalu}, {self.hvalu}, " \
93 f"{self.rlchk}, {self.valpar}])"