1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | // Components _MQTT(); _SparkplugB( AllmetricsList := _AllMetricsList ); _TryConnectTimer(); NumberOfDevices := _DeviceList.ListSize; _OnMQTT_Error(CLK := _MQTT.ClientError(eError => _MQTT_eError)); IF _OnMQTT_Error.Q THEN // Goto Error State _EoNState := EoNStateType.ERROR; END_IF // MQTT DisConnected? => the statemachine is pushed to EoNStateType.EXITING _OnEoNDisConnect( CLK := NOT Connect ); IF _OnEoNDisConnect.Q THEN // Stop state machine in proper fashion _EoNState := EoNStateType.DISCONNECTING; CASE _EoNState OF EoNStateType.ERROR : // No MQTT Client ERROR AND Connected => we goto RECONNECTING _TryConnectTimer.Enable := TRUE; IF _TryConnectTimer.Out THEN IF (TIME_TO_UDINT(_TryConnectTimer.OutTimeRemaining - T#1MS) MOD 15000) <= 2 * _taskCycleTime THEN // still needs some refinement IF NOT _Already1 THEN // check connection state and goto next step if connected // Resubscribe again which will trigger a ReBirth _MQTT.UnsubscribeDCMD(); _SubscribeDCMD := FALSE; _MQTT.UnsubscribeNCMD(); _SubscribeNCMD := FALSE; _TryConnectTimer.Enable := FALSE; END_IF; _Disconnect := _MQTT.Disconnect(); WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN Next Attempt in: %s s', UDINT_TO_STRING(TO_UDINT(_TryConnectTimer.LockTimeRemaining) / 1000)); END_IF; _Already2 := TRUE; _Already2 := FALSE; END_IF END_IF; _CurConnectionState := SparkplugSessionStateType.OFFLINE; EoNStateType.INIT : IF NOT _Initialised THEN _EoNState := EoNStateType.CONNECTING; END_IF EoNStateType.CONNECTING : _Disconnect := _MQTT.Disconnect(); IF NOT _Already4 THEN _Already4 := TRUE; _Already4 := FALSE; END_IF; EoNStateType.SUBSCRIBE_NCMD : // Subscribe to NCMD IF NOT _SubscribeNCMD THEN _NodeBirthPublished := PublishNBIRTH( LWT_BdSeq := _NDEATH.Value, AllMetricsList := THIS^._AllMetricsList ); _EoNState := EoNStateType.ONLINE; EoNStateType.ONLINE : // Just pass the Ref, no copying of data _RecvMesg REF= _MQTT.GetNCMDMessage( MessageTopic => _RecvTopic ); onNCMDMessage( pTopic := ADR(_RecvTopic), pMessage := _RecvMesg, Rebirth => _Rebirth ); _EoNState := EoNStateType.DISCONNECTING; IF _MQTT.DCMDMessageReceived() THEN //This will need to be fixed, once DCMDs are implemented //_RecvMesg REF= _MQTT.GetDCMDMessage( MessageTopic => _RecvTopic ); onDCMDMessage( pTopic := ADR(_RecvTopic), pMessage := ADR(_RecvMesg) ); // If we are rebirthing, then do not check IF (NOT _PublishBlocked) AND (NOT _Rebirth) THEN IF NOT(_NDATAEncoderPrepared) OR _ChangeDetected THEN _NDATAEncoderPrepared := PrepareNDATA( AllMetricsList := _AllMetricsList ); // Detect EoN data changes and feed them to the encoder for NDATA payload _ChangeError := _SparkplugB.FindChanges(arSparkplugBoolean:= arSparkplugBoolean, arSparkplugFloat:= arSparkplugFloat, arSparkplugInt8:= arSparkplugInt8, arSparkplugInt32:= arSparkplugInt32, arSparkplugUInt8:= arSparkplugUInt8, arSparkplugUInt32:= arSparkplugUInt32, arSparkplugUUID:= arSparkplugUUID, arSparkplugString:= arSparkplugString, ChangeDetected => _ChangeDetected, NumberOfChanges => _CurrentChanges); IF _ChangeError <> ERROR.NO_ERROR OR _ErrorDetected THEN WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN FindChanges Error: %s', TO_STRING(_ChangeError) ); IF _NDATAEncoderPrepared AND _ChangeDetected THEN WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN FindChanges Detected: %s', TO_STRING(_CurrentChanges) ); _PublishNDATAError := PublishNDATA( AllMetricsList := _AllMetricsList ); _PublishBlockTimerEnable := _ChangeDetected AND NOT _PublishBlocked; PT := UINT_TO_TIME(publishPeriod), ET => _PublishBlockTimerElapsed); EoNStateType.DISCONNECTING : // To Exit Cleanly we have to do the following in this exact order: // 1) DISABLE_PUBLISHER => Stop the publisher // 2) UNSUBSCRIBE_DCMD => Unsubscribe from DCMD while still connected // 3) UNSUBSCRIBE_NCMD => Unsubscribe from NCMD while still connected // 4) DISCONNECT_MQTT =>Disconnect the MQTT Client // REBIRH => INIT // OTHERWISE => OFFLINE WriteDeviceLog( UDINT_TO_DWORD(CmpLog.LogClass.LOG_INFO), 'EoN Disconnection Requested %s',WAIT); _EoNState := EoNStateType.DISABLE_PUBLISHER; EoNStateType.UNSUBSCRIBE_DCMD : EoNStateType.UNSUBSCRIBE_NCMD : |