Coverage for C:\Users\hjanssen\HOME\pyCharmProjects\ethz_hvl\hvl_ccb\hvl_ccb\dev\supercube\constants.py : 0%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Copyright (c) 2019-2020 ETH Zurich, SIS ID and HVL D-ITET
2#
3"""
4Constants, variable names for the Supercube OPC-connected devices.
5"""
7from typing import cast, Sequence, Sized, Tuple
9from aenum import IntEnum, EnumMeta
11from hvl_ccb.utils.enum import ValueEnum, unique
14@unique
15class SupercubeOpcEndpoint(ValueEnum):
16 """
17 OPC Server Endpoint strings for the supercube variants.
18 """
20 A = "Supercube Typ A"
21 B = "Supercube Typ B"
24# NOTE: super metaclass has to match metaclass of `super(GeneralSupport)`!
25class GeneralSupportMeta(EnumMeta):
26 def __new__(metacls, clsname, bases, clsdict, **kwargs):
27 cls = EnumMeta.__new__(
28 metacls, clsname, bases, clsdict, **kwargs
29 )
30 # BEWARE: keep manually in sync with suffixes of enum instances; opt use dir()
31 cls._port_range = range(1, 7)
32 cls._contact_range = range(1, 3)
33 return cls
36@unique
37class GeneralSupport(ValueEnum, metaclass=GeneralSupportMeta):
38 """
39 NodeID strings for the support inputs and outputs.
40 """
42 in_1_1 = '"Ix_Allg_Support1_1"'
43 in_1_2 = '"Ix_Allg_Support1_2"'
44 in_2_1 = '"Ix_Allg_Support2_1"'
45 in_2_2 = '"Ix_Allg_Support2_2"'
46 in_3_1 = '"Ix_Allg_Support3_1"'
47 in_3_2 = '"Ix_Allg_Support3_2"'
48 in_4_1 = '"Ix_Allg_Support4_1"'
49 in_4_2 = '"Ix_Allg_Support4_2"'
50 in_5_1 = '"Ix_Allg_Support5_1"'
51 in_5_2 = '"Ix_Allg_Support5_2"'
52 in_6_1 = '"Ix_Allg_Support6_1"'
53 in_6_2 = '"Ix_Allg_Support6_2"'
54 out_1_1 = '"Qx_Allg_Support1_1"'
55 out_1_2 = '"Qx_Allg_Support1_2"'
56 out_2_1 = '"Qx_Allg_Support2_1"'
57 out_2_2 = '"Qx_Allg_Support2_2"'
58 out_3_1 = '"Qx_Allg_Support3_1"'
59 out_3_2 = '"Qx_Allg_Support3_2"'
60 out_4_1 = '"Qx_Allg_Support4_1"'
61 out_4_2 = '"Qx_Allg_Support4_2"'
62 out_5_1 = '"Qx_Allg_Support5_1"'
63 out_5_2 = '"Qx_Allg_Support5_2"'
64 out_6_1 = '"Qx_Allg_Support6_1"'
65 out_6_2 = '"Qx_Allg_Support6_2"'
67 @classmethod
68 def port_range(cls) -> Sequence[int]:
69 """
70 Integer range of all ports.
72 :return: sequence of port numbers
73 """
74 return cls._port_range
76 @classmethod
77 def contact_range(cls) -> Sequence[int]:
78 """
79 Integer range of all contacts.
81 :return: sequence of contact numbers
82 """
83 return cls._contact_range
85 @classmethod
86 def _validate_port_contact_numbers(cls, port: int, contact: int):
87 """
88 Validate earthing stick number.
90 :param port: the port number
91 :param contact: the contact number
92 :raises ValueError: when port or contact number is not valid
93 """
94 if port not in cls.port_range():
95 raise ValueError(
96 f"Port number must be one of {list(cls.port_range())}"
97 )
98 if contact not in cls.contact_range():
99 raise ValueError(
100 f"Contact number must be one of {list(cls.contact_range())}"
101 )
103 @classmethod
104 def output(cls, port: int, contact: int):
105 """
106 Get the NodeID string for a support output.
108 :param port: the desired port (1..6)
109 :param contact: the desired contact at the port (1..2)
110 :return: the node id string
111 :raises ValueError: when port or contact number is not valid
112 """
113 cls._validate_port_contact_numbers(port, contact)
114 return getattr(cls, "out_{}_{}".format(port, contact))
116 @classmethod
117 def input(cls, port: int, contact: int):
118 """
119 Get the NodeID string for a support input.
121 :param port: the desired port (1..6)
122 :param contact: the desired contact at the port (1..2)
123 :return: the node id string
124 :raises ValueError: when port or contact number is not valid
125 """
126 cls._validate_port_contact_numbers(port, contact)
127 return getattr(cls, "in_{}_{}".format(port, contact))
130@unique
131class BreakdownDetection(ValueEnum):
132 """
133 Node ID strings for the breakdown detection.
135 TODO: these variable NodeIDs are not tested and/or correct yet.
136 """
138 #: Boolean read-only variable indicating whether breakdown detection and fast
139 #: switchoff is enabled in the system or not.
140 activated = '"Ix_Allg_Breakdown_activated"'
142 #: Boolean read-only variable telling whether the fast switch-off has triggered.
143 #: This can also be seen using the safety circuit state, therefore no method is
144 #: implemented to read this out directly.
145 triggered = '"Ix_Allg_Breakdown_triggered"'
147 #: Boolean writable variable to reset the fast switch-off. Toggle to re-enable.
148 reset = '"Qx_Allg_Breakdown_reset"'
151@unique
152class GeneralSockets(ValueEnum):
153 """
154 NodeID strings for the power sockets (3x T13 and 1xCEE16).
155 """
157 #: SEV T13 socket No. 1 (writable boolean).
158 t13_1 = '"Qx_Allg_Socket_T13_1"'
160 #: SEV T13 socket No. 2 (writable boolean).
161 t13_2 = '"Qx_Allg_Socket_T13_2"'
163 #: SEV T13 socket No. 3 (writable boolean).
164 t13_3 = '"Qx_Allg_Socket_T13_3"'
166 #: CEE16 socket (writeable boolean).
167 cee16 = '"Qx_Allg_Socket_CEE16"'
170T13_SOCKET_PORTS = (1, 2, 3)
171"""
172Port numbers of SEV T13 power socket
173"""
176@unique
177class Safety(ValueEnum):
178 """
179 NodeID strings for the basic safety circuit status and green/red switches "ready"
180 and "operate".
181 """
183 #: Status is a read-only integer containing the state number of the
184 #: supercube-internal state machine. The values correspond to numbers in
185 #: :class:`SafetyStatus`.
186 status = '"DB_Safety_Circuit"."si_safe_status"'
188 #: Writable boolean for switching to Red Ready (locked, HV off) state.
189 switch_to_ready = '"DB_Safety_Circuit"."sx_safe_switch_to_ready"'
191 #: Writable boolean for switching to Red Operate (locket, HV on) state.
192 switch_to_operate = '"DB_Safety_Circuit"."sx_safe_switch_to_operate"'
195class SafetyStatus(IntEnum):
196 """
197 Safety status values that are possible states returned from
198 :meth:`hvl_ccb.dev.supercube.base.Supercube.get_status`. These
199 values correspond to the states of the Supercube's safety circuit statemachine.
200 """
202 #: System is initializing or booting.
203 Initializing = 0
205 #: System is safe, lamps are green and some safety elements are not in place such
206 #: that it cannot be switched to red currently.
207 GreenNotReady = 1
209 #: System is safe and all safety elements are in place to be able to switch to
210 #: *ready*.
211 GreenReady = 2
213 #: System is locked in red state and *ready* to go to *operate* mode.
214 RedReady = 3
216 #: System is locked in red state and in *operate* mode, i.e. high voltage on.
217 RedOperate = 4
219 #: Fast turn off triggered and switched off the system. Reset FSO to go back to a
220 #: normal state.
221 QuickStop = 5
223 #: System is in error mode.
224 Error = 6
227@unique
228class Power(ValueEnum):
229 """
230 Variable NodeID strings concerning power data.
232 TODO: these variable NodeIDs are not tested and/or correct yet, they don't exist
233 yet on Supercube side.
234 """
236 #: Primary voltage in volts, measured by the frequency converter at its output.
237 #: (read-only)
238 voltage_primary = "Qr_Power_FU_actual_Voltage"
240 #: Primary current in ampere, measured by the frequency converter. (read-only)
241 current_primary = "Qr_Power_FU_actual_Current"
243 #: Power setup that is configured using the Supercube HMI. The value corresponds to
244 #: the ones in :class:`PowerSetup`. (read-only)
245 setup = "Qi_Power_Setup"
247 #: Voltage slope in V/s.
248 voltage_slope = "Ir_Power_dUdt"
250 #: Target voltage setpoint in V.
251 voltage_target = "Ir_Power_Target_Voltage"
253 #: Maximum voltage allowed by the current experimental setup. (read-only)
254 voltage_max = "Iw_Power_max_Voltage"
256 #: Frequency converter output frequency. (read-only)
257 frequency = "Ir_Power_FU_Frequency"
260class PowerSetup(IntEnum):
261 """
262 Possible power setups corresponding to the value of variable :attr:`Power.setup`.
263 """
265 #: No safety switches, use only safety components (doors, fence, earthing...)
266 #: without any power.
267 NoPower = 0
269 #: External power supply fed through blue CEE32 input using isolation transformer
270 #: and safety switches of the Supercube, or using an external safety switch
271 #: attached to the Supercube Type B.
272 External = 1
274 #: AC voltage with MWB transformer set to 50kV maximum voltage.
275 AC_SingleStage_50kV = 2
277 #: AC voltage with MWB transformer set to 100kV maximum voltage.
278 AC_SingleStage_100kV = 3
280 #: AC voltage with two MWB transformers, one at 100kV and the other at 50kV,
281 #: resulting in a total maximum voltage of 150kV.
282 AC_DoubleStage_150kV = 4
284 #: AC voltage with two MWB transformers both at 100kV, resulting in a total
285 #: maximum voltage of 200kV
286 AC_DoubleStage_200kV = 5
288 #: Internal usage of the frequency converter, controlling to the primary voltage
289 #: output of the supercube itself (no measurement transformer used)
290 Internal = 6
292 #: DC voltage with one AC transformer set to 100kV AC, resulting in 140kV DC
293 DC_SingleStage_140kV = 7
295 #: DC voltage with two AC transformers set to 100kV AC each, resulting in 280kV
296 #: DC in total (or a single stage transformer with Greinacher voltage doubling
297 #: rectifier)
298 DC_DoubleStage_280kV = 8
301class _PrefixedNumbersEnumBase(ValueEnum):
302 """
303 Base class for enums with "{prefix}{n}" instance names, where n=1..N.
304 """
306 @classmethod
307 def range(cls) -> Sequence[int]:
308 """
309 Integer range of all channels.
311 :return: sequence of channel numbers
312 """
313 return range(1, len(cast(Sized, cls))+1)
315 @classmethod
316 def _validate_number(cls, number: int):
317 """
318 Validate enum instance number.
320 :param number: the enum instance number (1..N)
321 :raises ValueError: when enum instance number is not in 1..N range
322 """
323 if number not in cls.range():
324 raise ValueError(
325 f"{cls._prefix()} number must be one of {list(cls.range())}"
326 )
328 @classmethod
329 def _prefix(cls) -> str:
330 """
331 Enum instances name prefix: "{prefix}{n}"
333 :return: enum instances prefix string
334 """
335 raise NotImplementedError("Implement in subclass")
337 @property
338 def number(self) -> int:
339 """
340 Get corresponding enum instance number.
342 :return: enum instance number (1..N)
343 """
344 # Py >=3.9: self.name.removeprefix()
345 return int(self.name[len(self._prefix()):])
347 # no type return as it would be a arguably too complex/obscure;
348 # cf. https://github.com/python/typing/issues/58#issuecomment-326240794
349 @classmethod
350 def get(cls, number: int):
351 """
352 Get the enum instance for a given number.
354 :param number: the instance number (1..N)
355 :return: the enum instance for the given number.
356 :raises ValueError: when instance number is not in the 1..N range
357 """
358 cls._validate_number(number)
359 return getattr(cls, f"{cls._prefix()}{number}")
362class _InputEnumBase(_PrefixedNumbersEnumBase):
363 """
364 Base class for enums with "input_{n}" instance names, where n=1..N.
365 """
367 @classmethod
368 def _prefix(cls) -> str:
369 return "input_"
371 @classmethod
372 def input(cls, channel: int):
373 """
374 Get the enum instance for a given channel number.
376 :param channel: the channel number (1..N)
377 :return: the enum instance for the given channel.
378 :raises ValueError: when channel number is not in the 1..N range
379 """
380 return cls.get(channel)
383MeasurementsScaledInput = unique(_InputEnumBase(
384 "MeasurementsScaledInput",
385 {
386 f"{_InputEnumBase._prefix()}{n}":
387 f'"DB_Measurements"."si_scaled_Voltage_Input_{n}"'
388 for n in range(1, 5)
389 }
390))
391"""
392Variable NodeID strings for the four analog BNC inputs for measuring voltage.
393The voltage returned in these variables is already scaled with the set ratio,
394which can be read using the variables in :class:`MeasurementsDividerRatio`.
395"""
398MeasurementsDividerRatio = unique(_InputEnumBase(
399 "MeasurementsDividerRatio",
400 {
401 f"{_InputEnumBase._prefix()}{n}":
402 f'"DB_Measurements"."si_Divider_Ratio_{n}"'
403 for n in range(1, 5)
404 }
405))
406"""
407Variable NodeID strings for the measurement input scaling ratios. These ratios
408are defined in the Supercube HMI setup and are provided in the python module here
409to be able to read them out, allowing further calculations.
410"""
413class EarthingStickStatus(IntEnum):
414 """
415 Status of an earthing stick. These are the possible values in the status integer
416 e.g. in :attr:`EarthingStick.status_1`.
417 """
419 #: Earthing stick is deselected and not enabled in safety circuit. To get out of
420 #: this state, the earthing has to be enabled in the Supercube HMI setup.
421 inactive = 0
423 #: Earthing is closed (safe).
424 closed = 1
426 #: Earthing is open (not safe).
427 open = 2
429 #: Earthing is in error, e.g. when the stick did not close correctly or could not
430 #: open.
431 error = 3
434class EarthingStickOperatingStatus(IntEnum):
435 """
436 Operating Status for an earthing stick. Stick can be used in auto or manual mode.
437 """
439 auto = 0
440 manual = 1
443class EarthingStickOperation(IntEnum):
444 """
445 Operation of the earthing stick in manual operating mode. Can be closed of opened.
446 """
448 open = 0
449 close = 1
452# NOTE: super metaclass has to match metaclass of `super(EarthingStick)`!
453class EarthingStickMeta(EnumMeta):
454 def __new__(metacls, clsname, bases, clsdict, **kwargs):
455 cls = EnumMeta.__new__(
456 metacls, clsname, bases, clsdict, **kwargs
457 )
458 # BEWARE: keep manually in sync with suffixes of enum instances; opt use dir()
459 cls._range = range(1, 7)
460 cls._statuses = tuple(
461 getattr(cls, f"status_{number}") for number in cls._range
462 )
463 cls._manuals = tuple(
464 getattr(cls, f"manual_{number}") for number in cls._range
465 )
466 cls._operating_statuses = tuple(
467 getattr(cls, f"operating_status_{number}") for number in cls._range
468 )
469 return cls
472@unique
473class EarthingStick(ValueEnum, metaclass=EarthingStickMeta):
474 """
475 Variable NodeID strings for all earthing stick statuses (read-only integer) and
476 writable booleans for setting the earthing in manual mode.
477 """
479 status_1 = '"DB_Safety_Circuit"."Earthstick_1"."si_HMI_Status"'
480 status_2 = '"DB_Safety_Circuit"."Earthstick_2"."si_HMI_Status"'
481 status_3 = '"DB_Safety_Circuit"."Earthstick_3"."si_HMI_Status"'
482 status_4 = '"DB_Safety_Circuit"."Earthstick_4"."si_HMI_Status"'
483 status_5 = '"DB_Safety_Circuit"."Earthstick_5"."si_HMI_Status"'
484 status_6 = '"DB_Safety_Circuit"."Earthstick_6"."si_HMI_Status"'
486 manual_1 = '"DB_Safety_Circuit"."Earthstick_1"."sx_earthing_manually"'
487 manual_2 = '"DB_Safety_Circuit"."Earthstick_2"."sx_earthing_manually"'
488 manual_3 = '"DB_Safety_Circuit"."Earthstick_3"."sx_earthing_manually"'
489 manual_4 = '"DB_Safety_Circuit"."Earthstick_4"."sx_earthing_manually"'
490 manual_5 = '"DB_Safety_Circuit"."Earthstick_5"."sx_earthing_manually"'
491 manual_6 = '"DB_Safety_Circuit"."Earthstick_6"."sx_earthing_manually"'
493 operating_status_1 = '"DB_Safety_Circuit"."Earthstick_1"."sx_manual_control_active"'
494 operating_status_2 = '"DB_Safety_Circuit"."Earthstick_2"."sx_manual_control_active"'
495 operating_status_3 = '"DB_Safety_Circuit"."Earthstick_3"."sx_manual_control_active"'
496 operating_status_4 = '"DB_Safety_Circuit"."Earthstick_4"."sx_manual_control_active"'
497 operating_status_5 = '"DB_Safety_Circuit"."Earthstick_5"."sx_manual_control_active"'
498 operating_status_6 = '"DB_Safety_Circuit"."Earthstick_6"."sx_manual_control_active"'
500 @property
501 def number(self) -> int:
502 """
503 Get corresponding earthing stick number.
505 :return: earthing stick number (1..6)
506 """
507 return int(self.name.rpartition("_")[-1])
509 @classmethod
510 def range(cls) -> Sequence[int]:
511 """
512 Integer range of all earthing sticks.
514 :return: sequence of earthing sticks numbers
515 """
516 return cls._range
518 @classmethod
519 def _validate_earthing_stick_number(cls, number: int):
520 """
521 Validate earthing stick number.
523 :param number: the earthing stick number
524 :raises ValueError: when earthing stick number is not valid
525 """
526 if number not in cls.range():
527 raise ValueError(
528 f"Earthing stick number must be one of {list(cls.range())}"
529 )
531 @classmethod
532 def statuses(cls) -> Tuple["EarthingStick", ...]:
533 """
534 Get all earthing stick status instances.
536 :return: tuple of status instances
537 """
538 return cls._statuses
540 @classmethod
541 def status(cls, number: int) -> "EarthingStick":
542 """
543 Get the status enum instance for an earthing stick number.
545 :param number: the earthing stick (1..6)
546 :return: the status instance
547 :raises ValueError: when earthing stick number is not valid
548 """
549 cls._validate_earthing_stick_number(number)
550 return cls.statuses()[number-1]
552 @classmethod
553 def manuals(cls) -> Tuple["EarthingStick", ...]:
554 """
555 Get all earthing stick manual instances.
557 :return: tuple of manual instances
558 """
559 return cls._manuals
561 @classmethod
562 def manual(cls, number: int):
563 """
564 Get the manual enum instance for an earthing stick number.
566 :param number: the earthing stick (1..6)
567 :return: the manual instance
568 :raises ValueError: when earthing stick number is not valid
569 """
570 cls._validate_earthing_stick_number(number)
571 return cls.manuals()[number-1]
573 @classmethod
574 def operating_statuses(cls) -> Tuple["EarthingStick", ...]:
575 """
576 Get all earthing stick operating status instances.
578 :return: tuple of operating status instances
579 """
580 return cls._operating_statuses
582 @classmethod
583 def operating_status(cls, number: int):
584 """
585 Get the operating status enum instance for an earthing stick number.
587 :param number: the earthing stick (1..6)
588 :return: the operating status instance
589 :raises ValueError: when earthing stick number is not valid
590 """
591 cls._validate_earthing_stick_number(number)
592 return cls.operating_statuses()[number-1]
595@unique
596class Errors(ValueEnum):
597 """
598 Variable NodeID strings for information regarding error, warning and message
599 handling.
600 """
602 #: Boolean read-only variable telling if a message is active.
603 message = '"DB_Message_Buffer"."Info_active"'
605 #: Boolean read-only variable telling if a warning is active.
606 warning = '"DB_Message_Buffer"."Warning_active"'
608 #: Boolean read-only variable telling if a stop is active.
609 stop = '"DB_Message_Buffer"."Stop_active"'
611 #: Writable boolean for the error quit button.
612 quit = '"DB_Message_Buffer"."Reset_button"'
615class _AlarmEnumBase(_PrefixedNumbersEnumBase):
616 """
617 Base class for enums with "Alarm{n}" instance names, where n=1..N.
618 """
620 @classmethod
621 def _prefix(cls) -> str:
622 return "Alarm"
624 @classmethod
625 def Alarm(cls, number: int):
626 """
627 Get the enum instance for a given alarm number.
629 :param number: the alarm number (1..N)
630 :return: the enum instance for the alarm number.
631 :raises ValueError: when alarm number is not in the 1..N range
632 """
633 return cls.get(number)
636Alarms = unique(_AlarmEnumBase(
637 "Alarms",
638 {
639 f"Alarm{n}":
640 f'"DB_Alarm_HMI"."Alarm{n}"'
641 for n in range(1, 152)
642 },
643))
644"""
645Alarms enumeration containing all variable NodeID strings for the alarm array.
646"""
649class DoorStatus(IntEnum):
650 """
651 Possible status values for doors.
652 """
654 #: not enabled in Supercube HMI setup, this door is not supervised.
655 inactive = 0
657 #: Door is open.
658 open = 1
660 #: Door is closed, but not locked.
661 closed = 2
663 #: Door is closed and locked (safe state).
664 locked = 3
666 #: Door has an error or was opened in locked state (either with emergency stop or
667 #: from the inside).
668 error = 4
671class EarthingRodStatus(IntEnum):
672 """
673 Possible status values for earthing rods.
674 """
675 #: earthing rod is somewhere in the experiment
676 #: and blocks the start of the experiment
677 experiment_blocked = 0
679 #: earthing rod is hanging next to the door, experiment is ready to operate
680 experiment_ready = 1
683class _DoorEnumBase(_PrefixedNumbersEnumBase):
684 """
685 Base class for enums with "status_{n}" instance names, where n=1..N is the door
686 number.
687 """
689 @classmethod
690 def _prefix(cls) -> str:
691 return "status_"
693 @classmethod
694 def status(cls, door: int):
695 """
696 Get the enum instance for a given door number.
698 :param number: the door number (1..N)
699 :return: the enum instance for the given door number.
700 :raises ValueError: when door number is not in the 1..N range
701 """
702 return cls.get(door)
705Door = unique(_DoorEnumBase(
706 "Door",
707 {
708 f"{_DoorEnumBase._prefix()}{n}":
709 f'"DB_Safety_Circuit"."Door_{n}"."si_HMI_status"'
710 for n in range(1, 4)
711 }
712))
713"""
714Variable NodeID strings for doors.
715"""
717EarthingRod = unique(_DoorEnumBase(
718 "EarthingRod",
719 {
720 f"{_DoorEnumBase._prefix()}{n}":
721 f'"DB_Safety_Circuit"."Door_{n}"."Ix_earthingrod"'
722 for n in range(1, 4)
723 }
724))
725"""
726Variable NodeID strings for earthing rods.
727"""
730class AlarmText(ValueEnum):
731 """
732 This enumeration contains textual representations for all error classes (stop,
733 warning and message) of the Supercube system. Use the :meth:`AlarmText.get`
734 method to retrieve the enum of an alarm number.
735 """
737 # Safety elements
738 Alarm1 = "STOP Emergency Stop 1"
739 Alarm2 = "STOP Emergency Stop 2"
740 Alarm3 = "STOP Emergency Stop 3"
741 Alarm4 = "STOP Safety Switch 1 error"
742 Alarm5 = "STOP Safety Switch 2 error"
743 Alarm6 = "STOP Door 1 lock supervision"
744 Alarm7 = "STOP Door 2 lock supervision"
745 Alarm8 = "STOP Door 3 lock supervision"
746 Alarm9 = "STOP Earthing stick 1 error while opening"
747 Alarm10 = "STOP Earthing stick 2 error while opening"
748 Alarm11 = "STOP Earthing stick 3 error while opening"
749 Alarm12 = "STOP Earthing stick 4 error while opening"
750 Alarm13 = "STOP Earthing stick 5 error while opening"
751 Alarm14 = "STOP Earthing stick 6 error while opening"
752 Alarm15 = "STOP Earthing stick 1 error while closing"
753 Alarm16 = "STOP Earthing stick 2 error while closing"
754 Alarm17 = "STOP Earthing stick 3 error while closing"
755 Alarm18 = "STOP Earthing stick 4 error while closing"
756 Alarm19 = "STOP Earthing stick 5 error while closing"
757 Alarm20 = "STOP Earthing stick 6 error while closing"
758 Alarm21 = "STOP Safety fence 1"
759 Alarm22 = "STOP Safety fence 2"
760 Alarm23 = "STOP OPC connection error"
761 Alarm24 = "STOP Grid power failure"
762 Alarm25 = "STOP UPS failure"
763 Alarm26 = "STOP 24V PSU failure"
765 # Doors
766 Alarm41 = "WARNING Door 1: Use earthing rod!"
767 Alarm42 = "MESSAGE Door 1: Earthing rod is still in setup."
768 Alarm43 = "WARNING Door 2: Use earthing rod!"
769 Alarm44 = "MESSAGE Door 2: Earthing rod is still in setup."
770 Alarm45 = "WARNING Door 3: Use earthing rod!"
771 Alarm46 = "MESSAGE Door 3: Earthing rod is still in setup."
773 # General
774 Alarm47 = "MESSAGE UPS charge < 85%"
775 Alarm48 = "MESSAGE UPS running on battery"
777 # generic not defined alarm text
778 not_defined = "NO ALARM TEXT DEFINED"
780 @classmethod
781 def get(cls, alarm: int):
782 """
783 Get the attribute of this enum for an alarm number.
785 :param alarm: the alarm number
786 :return: the enum for the desired alarm number
787 """
789 try:
790 return getattr(cls, "Alarm{}".format(alarm))
791 except AttributeError:
792 return cls.not_defined
795class OpcControl(ValueEnum):
796 """
797 Variable NodeID strings for supervision of the OPC connection from the
798 controlling workstation to the Supercube.
799 """
801 #: writable boolean to enable OPC remote control and display a message window on
802 #: the Supercube HMI.
803 active = '"DB_OPC_Connection"."sx_OPC_active"'
804 live = '"DB_OPC_Connection"."sx_OPC_lifebit"'
807class _LineEnumBase(_PrefixedNumbersEnumBase):
808 """
809 Base class for enums with "input_{n}" instance names, where n=1..N.
810 """
812 @classmethod
813 def _prefix(cls) -> str:
814 return "line_"
816 @classmethod
817 def line(cls, number: int):
818 """
819 Get the enum instance for a given line number.
821 :param number: the line number (1..M)
822 :return: the enum instance for the given line number.
823 :raises ValueError: when line number is not in the 1..N range
824 """
825 return cls.get(number)
828MessageBoard = unique(_LineEnumBase(
829 "MessageBoard",
830 {
831 f"{_LineEnumBase._prefix()}{n}":
832 f'"DB_OPC_Connection"."Is_status_Line_{n}"'
833 for n in range(1, 16)
834 }
835))
836"""
837Variable NodeID strings for message board lines.
838"""