Source code for pydevmgr_elt.devices.lamp.stat


from pydevmgr_core import  NodeAlias1, Defaults, NodeVar
from pydevmgr_elt.base import EltDevice,  GROUP
from pydevmgr_elt.base.tools import _inc, enum_group, enum_txt

from enum import Enum
Base = EltDevice.Stat

N = Base.Node # Base Node
NC = N.Config
ND = Defaults[NC] # this typing var says that it is a Node object holding default values 
NV = NodeVar # used in Data 
#                      _              _   
#   ___ ___  _ __  ___| |_ __ _ _ __ | |_ 
#  / __/ _ \| '_ \/ __| __/ _` | '_ \| __|
# | (_| (_) | | | \__ \ || (_| | | | | |_ 
#  \___\___/|_| |_|___/\__\__,_|_| |_|\__|
# 



class SUBSTATE(int, Enum):
    NONE                  =   0    
    NOTOP_NOTREADY        = 100    
    NOTOP_INITIALISING    = 102    
    NOTOP_READY_OFF       = 103    
    NOTOP_READY_ON        = 104    
    NOTOP_ERROR           = 199    
    OP_DISABLING          = 205    
    OP_OFF                = 206    
    OP_SWITCHING_OFF      = 207    
    OP_COOLING            = 208    
    OP_ON                 = 209    
    OP_SWITCHING_ON       = 210    
    OP_WARMING            = 211    
    OP_ERROR              = 299
    UNREGISTERED = -9999

# Add text definition to each constants, the definition is then accessible throught .txt attribute         
enum_group ({
        SUBSTATE.NONE                   : GROUP.UNKNOWN,
        SUBSTATE.NOTOP_NOTREADY         : GROUP.NOK,
        SUBSTATE.NOTOP_READY_OFF        : GROUP.NOK,
        SUBSTATE.NOTOP_READY_ON         : GROUP.NOK,
        SUBSTATE.NOTOP_INITIALISING     : GROUP.BUZY,
        SUBSTATE.NOTOP_ERROR            : GROUP.ERROR, 
  
        SUBSTATE.OP_DISABLING            : GROUP.BUZY, 
        SUBSTATE.OP_SWITCHING_OFF        : GROUP.BUZY,
        SUBSTATE.OP_SWITCHING_ON         : GROUP.BUZY,

        SUBSTATE.OP_COOLING              : GROUP.BUZY,
        SUBSTATE.OP_WARMING              : GROUP.BUZY,
        SUBSTATE.OP_ON                   : GROUP.OK,
        SUBSTATE.OP_OFF                  : GROUP.OK,
        SUBSTATE.OP_ERROR                : GROUP.ERROR,    
    })
    


class ERROR(int,  Enum):
    OK				      = _inc(0) # init the inc to zero 
    HW_NOT_OP           = _inc()
    INIT_FAILURE        = _inc()		
    UNEXPECTED_OFF      = _inc()
    UNEXPECTED_ON       = _inc()
    FAULT_SIG           = _inc()
    MAXON               = _inc()
    STILL_COOLING       = _inc()
    TIMEOUT_DISABLE     = _inc()
    TIMEOUT_INIT        = _inc()
    TIMEOUT_OFF         = _inc()
    TIMEOUT_ON          = _inc()
    # Simulator errors
    SIM_NOT_INITIALISED	= 90
    SIM_NULL_POINTER    = 100	

    UNREGISTERED = -9999

# Add text definition to each constants, the definition is then accessible throught .txt attribute     
enum_txt ({
    ERROR.OK:				   'OK',
	ERROR.HW_NOT_OP:			 'ERROR: TwinCAT not in OP state or CouplerState not mapped.',
    ERROR.INIT_FAILURE:		     'ERROR: INIT command aborted due to STOP or RESET.',
	ERROR.UNEXPECTED_OFF:		 'ERROR: Lamp unexpectedly switched OFF.',
	ERROR.UNEXPECTED_ON:		 'ERROR: Lamp unexpectedly switched ON.',
	ERROR.FAULT_SIG:			 'ERROR: Fault signal active.',
	ERROR.MAXON:				 'ERROR: Lamp maximum ON time exceeded.',
	ERROR.STILL_COOLING:		 'ERROR: ON command not allowed while cooling.',
	ERROR.TIMEOUT_DISABLE:	     'ERROR: Disable timed out.',
	ERROR.TIMEOUT_INIT:		     'ERROR: Init timed out.',
	ERROR.TIMEOUT_OFF:		     'ERROR: Switching OFF timed out.',
	ERROR.TIMEOUT_ON:			 'ERROR: Switching ON timed out.',
	ERROR.SIM_NOT_INITIALISED:   'ERROR: Lamp simulator not initialised.',
	ERROR.SIM_NULL_POINTER:	     'ERROR: NULL pointer to Lamp.',

    ERROR.UNREGISTERED:        'ERROR: Unregistered Error'
    })



    #  ____  _        _     ___       _             __                 
    # / ___|| |_ __ _| |_  |_ _|_ __ | |_ ___ _ __ / _| __ _  ___ ___  
    # \___ \| __/ _` | __|  | || '_ \| __/ _ \ '__| |_ / _` |/ __/ _ \ 
    #  ___) | || (_| | |_   | || | | | ||  __/ |  |  _| (_| | (_|  __/ 
    # |____/ \__\__,_|\__| |___|_| |_|\__\___|_|  |_|  \__,_|\___\___| 

class LampStat(Base):
    # Add the constants to this class 
    ERROR = ERROR
    SUBSTATE = SUBSTATE
    
    class Config(Base.Config):
        # define all the default configuration for each nodes. 
        # e.g. the suffix can be overwriten in construction (from a map file for instance)
        # all configured node will be accessible by the Interface
        check_time_left: ND = NC(suffix='stat.bCheckTimeLeft' )
        error_code: ND = NC(suffix='stat.nErrorCode' )
        intensity: ND = NC(suffix='stat.lrIntensity' )
        local: ND = NC(suffix='stat.bLocal' )
        state: ND = NC(suffix='stat.nState' )
        status: ND = NC(suffix='stat.nStatus' )
        substate: ND = NC(suffix='stat.nSubstate' )
        time_left: ND = NC(suffix='stat.nTimeLeft' )
    
    @NodeAlias1.prop(node="substate")
    def is_ready(self, substate):
        """ Alias node: True if lamp is ready (substate NOTOP_READY_ON or NOTOP_READY_OFF) """
        return substate in [self.SUBSTATE.NOTOP_READY_ON, self.SUBSTATE.NOTOP_READY_OFF]
    
    @NodeAlias1.prop(node="substate")
    def is_off(self, substate):
        """  Alias node: True if lamp is off """
        return substate == self.SUBSTATE.OP_OFF
    
    @NodeAlias1.prop(node="substate")
    def is_on(self, substate):
        """  Alias node: True if lamp is on """
        return substate == self.SUBSTATE.OP_ON



    # We can add some nodealias to compute some stuff on the fly 
    # If they node to be configured one can set a configuration above 
    
    # Node Alias here     
    # Build the Data object to be use with DataLink, the type and default are added here 
    class Data(Base.Data):
        check_time_left: NV[bool] = False
        error_code: NV[int] = 0
        intensity: NV[float] = 0.0
        local: NV[bool] = False
        state: NV[int] = 0
        status: NV[int] = 0
        substate: NV[int] = 0
        time_left: NV[int] = 0


if __name__ == "__main__":
    LampStat( local=NC(parser=float) )