diff --git a/RCUSCC/RCUSCC/RCUSCC.py b/RCUSCC/RCUSCC/RCUSCC.py index 90fa69337a05b8d70ca165b8534c1d168c6b2b7d..a8d697845a8fdf98fe5b6ca8065ac46d80c3a513 100644 --- a/RCUSCC/RCUSCC/RCUSCC.py +++ b/RCUSCC/RCUSCC/RCUSCC.py @@ -44,21 +44,23 @@ class RCUSCC(Device): - Type:'DevDouble' States are as follows: - ON = Device is functional and controls the hardware, - OFF = Device is turned off, drops connection to the hardware, - FAULT = Device detected an unrecoverable error, and is malfunctional, - INIT = Device is initialising. + INIT = Device is initialising. + STANDBY = Device is initialised, but pends external configuration and an explicit turning on, + ON = Device is fully configured, functional, controls the hardware, and is possibly actively running, + FAULT = Device detected an unrecoverable error, and is thus malfunctional, + OFF = Device is turned off, drops connection to the hardware, The following state transitions are implemented: - boot -> INIT: Device will initialise when it is started, - INIT -> ON: Device will report to be functional when initialisation succeeds - INIT -> FAULT: Device will degrade to malfunctional if initialisation fails - ON -> FAULT: Device will degrade to malfunctional if an unrecoverable error is encountered - * -> OFF: Device is turned off. Triggered by the Off() command. - FAULT -> INIT: Device is reinitialised to recover from an error. Triggered by the Init() command. - OFF -> INIT: Device is turned on again. Triggered by the Init() command. - - For integration testing reasons, the user is allowed to manually set the device to FAULT. + boot -> INIT: Triggered by device. Device will initialise when it is started, + INIT -> STANDBY: Triggered by device. Device is initialised, and is ready for additional configuration by the user, + STANDBY -> ON: Triggered by user. Device reports to be functional, + * -> FAULT: Triggered by device. Device has degraded to malfunctional, for example because the connection to the hardware is lost, + * -> FAULT: Triggered by user. Emulate a forced malfunction for integration testing purposes, + * -> OFF: Triggered by user. Device is turned off. Triggered by the Off() command, + FAULT -> INIT: Triggered by user. Device is reinitialised to recover from an error, + OFF -> INIT: Triggered by user. Device is turned on again. + + The user triggers their transitions by the commands reflecting the target state (Init(), On(), Fault()). """ client = 0 name_space_index = 0 @@ -274,9 +276,10 @@ class RCUSCC(Device): self.client = opcua.Client("opc.tcp://{}:{}/".format(self.OPC_Server_Name, self.OPC_Server_Port), self.OPC_Time_Out) # timeout in seconds - # Connect to OPC-UA -- will set ON state on success - self.opcua_connection = OPCUAConnection(self.client, self.On, self.Fault, self) + # Connect to OPC-UA -- will set ON state on success in case of a reconnect + self.opcua_connection = OPCUAConnection(self.client, self.Standby, self.Fault, self) + # Explicitly connect if not self.opcua_connection.connect(): # hardware or infra is down -- needs fixing first self.Fault() @@ -293,8 +296,8 @@ class RCUSCC(Device): # Start keep-alive self.opcua_connection.start() - # Everything went ok -- go online - self.set_state(DevState.ON) + # Everything went ok -- go standby. + self.set_state(DevState.STANDBY) def always_executed_hook(self): @@ -452,6 +455,29 @@ class RCUSCC(Device): self.init_device() + @only_in_states([DevState.INIT]) + def Standby(self): + """ + Command to ask for initialisation of this device. Can only be called in FAULT or OFF state. + + :return:None + """ + + self.set_state(DevState.STANDBY) + + @command( + ) + @only_in_states([DevState.STANDBY]) + @DebugIt() + def On(self): + """ + Command to ask for initialisation of this device. Can only be called in FAULT or OFF state. + + :return:None + """ + + self.set_state(DevState.ON) + @command( ) @DebugIt() @@ -476,7 +502,7 @@ class RCUSCC(Device): @command( ) - @only_in_states([DevState.ON, DevState.INIT]) + @only_in_states([DevState.ON, DevState.INIT, DevState.STANDBY]) @DebugIt() def Fault(self): """