--- a/branches/FeatureBranches/PrimaryHost/SparkplugB/Function Blocks/FB_PrimaryHost/FB_PrimaryHost/svnobj
+++ b/branches/FeatureBranches/PrimaryHost/SparkplugB/Function Blocks/FB_PrimaryHost/FB_PrimaryHost/svnobj
@@ -1,5 +1,5 @@
-Gx_l\p!0…jüo–Y4ÍžئSystem.StringL{6f9dac99-8de1-4efc-8465-68ac443b7d08}SpecialFuncL{0db3d7bb-cde0-4416-9a7b-ce49a0124323}NoneImplementationL{3b83b776-fb25-43b8-99f2-3c507c9143fc}TextDocument	L{f3878285-8e4f-490b-bb1b-9acbb7eb04db}
-TextLinesL{a5de0b0b-1cb5-4913-ac21-9d70293ec00d}Id
longTagText// Componentsn_MQTT.IASyncPropertyProvider( IASyncPropertyProvider );b_MQTT.ITLSContextProvider( ITLSContextProvider );_MQTT();¸Connected := (NOT _MQTT.ClientError() AND NOT _MQTT.IsConnecting() AND _MQTT.IsConnected());b_SparkplugB( AllmetricsList := _AllMetricsList );RIF _MQTT.SubscriberMessageReceived() THENà    _RecvMesg REF= _MQTT.GetSubscriberMessage(MetricList := THIS^._AllMetricsList, MessageTopic => _RecvTopic );l    //onSubscribeMessage( pTopic := ADR( _RecvTopic ),d    //                    pMessage := _RecvMesg );‚    _TopicParser( pTopic := ADR(_RecvTopic) ); //parses the topic    ~    WriteDeviceLog( UDINT_TO_DWORD( CmpLog.LogClass.LOG_INFO ),j                    'PrimaryHost Received Topic: %s',x                    TO_STRING( _TopicParser.MessageType ) ); z    CASE _TopicParser.MessageType OF  //SparkplugMessageTypes!š        SparkplugMessageTypes.NBIRTH: //Birth certificate for MQTT EoN nodes."            _MyEdge REF= THIS^.GetEdge( GroupId := _TopicParser.GroupId,#Š                                       EdgeId := _TopicParser.EdgeId,$‚                                       eError => _HandledError );%B            CASE _HandledError OF&p                ERROR.GroupIDNotFound: // ==> NEW GROUP!'°                    _MyGroupId REF= THIS^.allocGroupId( GroupId := _TopicParser.GroupId,(”                                                       eError => eError );)f                    IF eError = ERROR.NO_ERROR THEN*º                        _MyEdge REF= THIS^.allocEdgetoGroupId( EdgeId := _TopicParser.EdgeId,+Ä                                                              itfGroupID := _MyGroupId.itfGroupID,,¢                                                              eError => eError );-n                        IF eError = ERROR.NO_ERROR THEN.–                            _MyEdge.ProcessNBIRTH( itfPrimaryHost := THIS^,/                                                  pMessage := _RecvMesg,0†                                                  xError => xError,1Š                                                  eError => eError );28                        ELSE3V                            xError := TRUE;4^                            //eError := eError;5<                        END_IF60                    ELSE7N                        xError := TRUE;8V                        //eError := eError;94                    END_IF:l                ERROR.EdgeIDNotFound: // ==> NEW EDGE!;¬                    _MyGroupId REF= THIS^.GetGroupID( GroupId := _TopicParser.GroupId,<                                                     eError => eError );=v                ERROR.NO_ERROR: // ==> UPDATE EXISTING EDGE>†                    _MyEdge.ProcessNBIRTH( itfPrimaryHost := THIS^,?€                                          pMessage := _RecvMesg,@v                                          xError => xError,Az                                          eError => eError );B             ELSECz                ; //{info 'TODO: maybe some sort of error??'}D(            END_CASEE            Fr        SparkplugMessageTypes.NDATA: //Node data message.G‚                                   EdgeId := _TopicParser.EdgeId,Hz                                   eError => _HandledError );I„                    _MyEdge.ProcessNDATA( itfPrimaryHost := THIS^,J>                xError := TRUE;K^                eError := Error.MetricNotFound;L–                WriteDeviceLog( UDINT_TO_DWORD( CmpLog.LogClass.LOG_INFO ),Mš                                'PrimaryHost process NDATA metric error: %s',N~                                TO_STRING( _HandledError ) );  Ob            END_CASE                             PF                                   Qš        SparkplugMessageTypes.NDEATH: //Death certificate for MQTT EoN nodes.RV            eError := ERROR.NotImplemented;SŠ        SparkplugMessageTypes.DBIRTH: //Birth certificate forDevices.T˜            _MyDevice REF= THIS^.GetDevice( GroupId := _TopicParser.GroupId,U’                                           EdgeId := _TopicParser.EdgeId,Vš                                           DeviceId := _TopicParser.DeviceId,WŠ                                           eError => _HandledError );Xž                ERROR.GroupIDNotFound:  // ==> NEW GROUP! must rebirth the edgeYœ                ERROR.EdgeIDNotFound:   // ==> NEW EDGE! must rebirth the edgeZt                ERROR.DeviceIDNotFound: // ==> NEW DEVICE![Š                ERROR.NO_ERROR:         // ==> UPDATE EXISTING DEVICE\”        SparkplugMessageTypes.DDEATH,    //Death certificate for Devices. ]€            SparkplugMessageTypes.DDATA: //Device data message. ^€        SparkplugMessageTypes.NCMD,      //Node command message._„            SparkplugMessageTypes.DCMD,  //Device command message.`š            SparkplugMessageTypes.STATE: //Critical application state messagea†            ;                            //do nothing, ignore theseb    ELSEcj        ; //{info 'TODO: maybe some sort of error??'}d    END_CASEe  fEND_IFgv_ExponentialBackOff( Enable := (Connect AND NOT Connected),hn                     ConnectionTime := _ConnectionTime,in                     LockTimesArray := _LockTimesArray,jR                     Enabled => _Enabled,kv                     OutTimeRemaining => _OutTimeRemaining,l~                     LockTimeRemaining => _LockTimeRemaining );md_StateMachine( Connect := _ExponentialBackOff.out,nb               PrimaryHostConnected := Connected,oJ               pMQTT := ADR( _MQTT ),pb               pSparkplugB := ADR( _SparkplugB ),qH               pPrimaryHost := THIS,r\               SessionState => SessionState );sDiag();tInterfaceuL{a9ed5b7e-75c5-4651-af16-d2c27e98cb94}v(*w*    Primary Host NodexÖ    Allows you to concenrate Edge of Network Data sent by various Edges or other Sparkplug compatible nodesy*)z0{attribute 'reflection'}{jFUNCTION_BLOCK FB_PrimaryHost IMPLEMENTS IPrimaryHost|VAR_INPUT}€    ServerUrl     : STRING;          // eg:'test.mosquitto.org';~`    ServerPort    : UINT    := 1883; // eg: 1883r    PrimaryHostID : WSTRING := "";   // eg:'PrimaryHost';€ˆ    KeepAlive     : UINT    := 60;   // eg: 60 (Value is in seconds)V    // Persistent Session (FALSE = DEFAULT)‚°    //  * The client must get all messages from a certain topic, even if it is offline. ƒò    //  * You want the broker to queue the messages for the client and deliver them as soon as the client is back online.„X    //  * The client has limited resources. …ˆ    //  * You want the broker to store the subscription information of the client and restore the interrupted communication quickly.†È    //  * The client needs to reNumberOfMetricse all QoS 1 and 2 publish messages after a reconnect.‡    //  ˆ8    //  Clean session (TRUE)‰à    //  * The client needs only to publish messages to topics, the client does not need to subscribe to topics. ŠÞ    //  * You don t want the broker to store session information or retry transmission of QoS 1 and 2 messages.‹–    //  * The client does not need to get messages that it misses offline. Œ    //H    CleanSession : BOOL    := FALSE;Ž¦    Username     : WSTRING := "";           // specify a username if any (optional)¾    Password     : WSTRING := "";           // specify the password for the username (optional)º    UseTLS       : BOOL;                    // Enables usage of the TLS encryption (optional)‘T    hCert        : SysTypes.RTS_IEC_HANDLE’ü    ;                                           // Handle to the client certificate (optional) and only used if UseTLS is TRUE“\    ITLSContextProvider : MQTT.NBS.ITLSContext”¢    ; //Encapsulates all the data neccessaray to handle encrypted tcp connections•ˆ    //Static initialization, as shown in the following code snippet;–    //VAR—V    //    commonName : STRING := 'MyRasPi';˜¸    //    ciCertInfo : NBS.CERT_INFO := (psInfo:=ADR(commonName), udiSize:=LEN(commonName));™X    //    myTLSContext : NBS.TLSContext := (š`    //        ePurpose:=NBS.PURPOSE.CLIENT_SIDE,›L    //        sUseCaseName:='NBSTest',œB    //        sTLSVersion:='1.3',J    //        ciCertInfo:=ciCertInfo,žH    //        udiVerificationMode:=2Ÿ    //    );     //END_VAR¡š    IASyncPropertyProvider : MQTT.NBS.IAsyncProperty; // Runs the connect process in a own background task. Use this property if the connection setup takes longer than one task cycle (e.g. TLS connections)¢END_VAR£VAR_OUTPUT¤4    Connected      : BOOL;¥^    SessionState   : SparkplugSessionStateType;¦4    xError         : BOOL;§6    eError         : ERROR;¨^    itfPrimaryHost : IPrimaryHost := THIS^;    ©VARªÐ    _groupIDPool        : List;         // OF FB_GroupID - This is blank groupids for dynamic allocation«v    _EdgePool           : List;         // OF FB_RemoteEdge¬z    _DevicePool         : List;         // OF FB_RemoteDevice­z    _MetricPool         : List;         // OF FB_RemoteMetric®¬    _groupIDs           : List;         // OF FB_GroupID - This is groupIDs with names¯¦    Connect             : BOOL := TRUE; // TRUE: Connects EoN using the configured settings, FALSE: Disconnects EoN from server if it was connected°¼    _cPrimaryHostID     : WSTRING;   // Corrected PrimaryHostID, contains no illegal chars    ±>    _Enabled            : BOOL;²P    _ConnectionTime     : TIME := T#30S;³¨    _LockTimesArray     : ARRAY[1..8] OF TIME := [4(TIME#30S0MS), 2(TIME#1M0S0MS), TIME#2M0S0MS, TIME#4M0S0MS]; // could be made accessible public  ´ž    _OutTimeRemaining   : TIME; // Duration of Out Time Period = TRUE remainingµ>    _LockTimeRemaining  : TIME;¶¾    _ExponentialBackOff : FB_ExponentialBackOffTimer; // Handles the Exponential Backoff timing·j    _StateMachine       : FB_PrimaryHostStateMachine;¸l    _TopicProvider      : FB_PrimaryHostTopicProvider;¹Z    _MQTT               : FB_PrimaryHostMQTT;ºT    _MQTT_eError        : MQTT.MQTT_ERROR;»ž    _SparkplugB         : FB_SparkplugBSimple;     // Handles SparkPlugB Stuff ¼š    _AllMetricsList     : LIST;                    // Of FB_HostStorageMetric½¢    _Blob               : ARRAY[0..65535] OF BYTE; // buffer for encoded messages¾¤    _BlobSize           : UDINT;                   // current encoded message size¿|    _LastWillQos        : MQTT.MQTT_QOS := MQTT.MQTT_QOS.QoS0;ÀP    _LastWillRetain     : BOOL := FALSE;Á’    _LastWillTopic      : WSTRING(GC_Sparkplug.supported_string_lengths);ª    _NDEATH             : FB_SparkplugUInt64;    // contains the current NDEATH BDSeqú    _NDEATHPayload      : ARRAY[0..255] OF BYTE; // what is the maximum size of this payload?Ä@    _NDEATHPayloadSize  : UDINT;Å~    _RecvMesg           : REFERENCE TO FB_PayloadSimpleDecoder;Æ’    _RecvTopic          : WSTRING(GC_Sparkplug.supported_string_lengths);Çâ    _HandledError       : ERROR; // an error that will be given back by a function, but we can handle the error. Èd    _MyGroupId          : REFERENCE TO FB_GroupId;Éj    _MyEdge             : REFERENCE TO FB_RemoteEdge;Ên    _MyDevice           : REFERENCE TO FB_RemoteDevice;ËR    _TopicParser        : FB_TopicParser;ÌB    _Diag               : STRING;Í>    {attribute 'instance-path'}Î0    {attribute 'noinit'}Ï$    _POU : STRING;Ð"UniqueIdGeneratorÑ2264ÒPOULevelÓL{8e575c5b-1d37-49c6-941b-5c0ec7874787}ÔStandardÕ ChildObjectGuidsÖ8System.Collections.ArrayList×,AddAttributeSubsequentØboolÐÐ-ÐÐ	E
-ŽÐÐ
­CÚÐ-ÐÐ
­DÚÐ-ÐÐ
­EÚÐ-ÐÐ
­FÚÐ-ÐÐ
­GÚÐ-ÐÐ
­HÚÐ-ÐÐ
­ºÚÐ-ÐÐ
­IÚÐ-ÐÐ
­JÚÐ-ÐÐ
­KÚÐ-ÐÐ
­LÚÐ-ÐÐ
­MÚÐ-ÐÐ
­NÚÐ-ÐÐ
­OÚÐ-ÐÐ
­PÚÐ-ÐÐ
­QÚÐ-ÐÐ
­RÚÐ-ÐÐ
­SÚÐ-ÐÐ
­TÚÐ- ÐÐ
­UÚÐ-!ÐÐ
­VÚÐ-"ÐÐ
­WÚÐ-#ÐÐ
­XÚÐ-$ÐÐ
­ÂÚÐ-ÐÐ
­YÚÐ-%ÐÐ
­ZÚÐ-&ÐÐ
­[ÚÐ-'ÐÐ
­\ÚÐ-(ÐÐ
­]ÚÐ-ÐÐ
­^ÚÐ-)ÐÐ
­_ÚÐ-*ÐÐ
­`ÚÐ-+ÐÐ
­aÚÐ-,ÐÐ
­bÚÐ-ÐÐ
­cÚÐ--ÐÐ
­dÚÐ-.ÐÐ
­eÚÐ-/ÐÐ
­fÚÐ-0ÐÐ
­gÚÐ-1ÐÐ
­hÚÐ-2ÐÐ
­iÚÐ-3ÐÐ
­jÚÐ-4ÐÐ
­kÚÐ-5ÐÐ
­lÚÐ-6ÐÐ
­mÚÐ-7ÐÐ
­nÚÐ-8ÐÐ
­oÚÐ-9ÐÐ
­pÚÐ-:ÐÐ
­qÚÐ-;ÐÐ
­rÚÐ-<ÐÐ
­sÚÐ-ÐÐ
­tÚÐ-)ÐÐ
­uÚÐ-*ÐÐ
­vÚÐ-+ÐÐ
­wÚÐ-,ÐÐ
­xÚÐ-ÐÐ
­yÚÐ--ÐÐ
­zÚÐ-.ÐÐ
­{ÚÐ-/ÐÐ
­|ÚÐ-0ÐÐ
­}ÚÐ-1ÐÐ
­~ÚÐ-2ÐÐ
­ÚÐ-3ÐÐ
­€ÚÐ-4ÐÐ
­ÚÐ-5ÐÐ
­‚ÚÐ-6ÐÐ
­ƒÚÐ-7ÐÐ
­„ÚÐ-8ÐÐ
­…ÚÐ-9ÐÐ
­†ÚÐ-=ÐÐ
­‡ÚÐ->ÐÐ
­ˆÚÐ-?ÐÐ
­‰ÚÐ-@ÐÐ
­ŠÚÐ-AÐÐ
­‹ÚÐ-BÐÐ
­ŒÚÐ-CÐÐ
­ÚÐ-DÐÐ
­ÃÚÐ-EÐÐ
­¾ÚÐ-FÐÐ
­ÄÚÐ-"ÐÐ
­ÅÚÐ-GÐÐ
­ÀÚÐ-HÐÐ
­ÇÚÐ-%ÐÐ
­ÍÚÐ-=ÐÐ
­ÎÚÐ-IÐÐ
­ÏÚÐ-?ÐÐ
­ÐÚÐ-@ÐÐ
­ÑÚÐ-AÐÐ
­ÒÚÐ-BÐÐ
­ÕÚÐ-JÐÐ
­ÖÚÐ-KÐÐ
­×ÚÐ-LÐÐ
­ØÚÐ-MÐÐ
­ÓÚÐ-NÐÐ
­ÈÚÐ-OÐÐ
­ÆÚÐ-PÐÐ
­¿ÚÐ-EÐÐ
­ŽÚÐ-QÐÐ
­ÚÐ-RÐÐ
­»ÚÐ-EÐÐ
­ÚÐ-SÐÐ
­‘ÚÐ-TÐÐ
­’ÚÐ-UÐÐ
­“ÚÐ-VÐÐ
­”ÚÐ-WÐÐ
­•ÚÐ-ÐÐ
­–ÚÐ-%ÐÐ
­—ÚÐ-XÐÐ
­˜ÚÐ-YÐÐ
­™ÚÐ-ZÐÐ
­šÚÐ-[ÐÐ
­›ÚÐ-BÐÐ
­œÚÐ-CÐÐ
­ÚÐ-DÐÐ
­žÚÐ-\ÐÐ
­ ÚÐ-]ÐÐ
­¡ÚÐ-RÐÐ
­¢ÚÐ-^ÐÐ
­£ÚÐ-_ÐÐ
­¤ÚÐ-`ÐÐ
­¥ÚÐ-aÐÐ
­¦ÚÐ-bÐÐ
­§ÚÐ-cÐÐ
­¨ÚÐ-dÐÐ
­©ÚÐ-eÐÐ
­ªÚÐ-fÐÐ
­«ÚÐ-ÐÐ
­¬ÚÐ-gÐÐ
­­ÚÐ-hÐÐ
­®ÚÐ-iÐÐ
­¯ÚÐ-jÐÐ
­°ÚÐ-kÐÐ
­±ÚÐ-lÐÐ
­²ÚÐ-ÐÐ
­³ÚÐ-mÐÐ
­´ÚÐ-nÐÐ
­µÚÐ-oÐÐ
­¶ÚÐ-pÐÐ
­·ÚÐ-qÐÐ
­¸ÚÐ-rÐÐ
­¹ÚÐ-ÐÐ
­…ÚÐ-sÐtuÐ	E
-]ÐÐ
­ÚÚÐ-vÐÐ
­ÛÚÐ-wÐÐ
­ÜÚÐ-xÐÐ
­ÝÚÐ-yÐÐ
­ÞÚÐ-zÐÐ
­ßÚÐ-{ÐÐ
­àÚÐ-|ÐÐ
­áÚÐ-}ÐÐ
­âÚÐ-~ÐÐ
­ãÚÐ-ÐÐ
­äÚÐ-€ÐÐ
­åÚÐ-ÐÐ
­æÚÐ-‚ÐÐ
­çÚÐ-ƒÐÐ
­èÚÐ-„ÐÐ
­éÚÐ-…ÐÐ
­êÚÐ-†ÐÐ
­ëÚÐ-‡ÐÐ
­ìÚÐ-ˆÐÐ
­íÚÐ-‰ÐÐ
­îÚÐ-ŠÐÐ
­ïÚÐ-‹ÐÐ
­ðÚÐ-ŒÐÐ
­ñÚÐ-ÐÐ
­òÚÐ-ŽÐÐ
­óÚÐ-ÐÐ
­ôÚÐ-ÐÐ
­õÚÐ-‘ÐÐ
­öÚÐ-’ÐÐ
­÷ÚÐ-“ÐÐ
­øÚÐ-”ÐÐ
­ùÚÐ-•ÐÐ
­úÚÐ-ŒÐÐ
­ûÚÐ-–ÐÐ
­üÚÐ-—ÐÐ
­ýÚÐ-˜ÐÐ
­þÚÐ-™ÐÐ
­ÿÚÐ-šÐÐ
­ÚÐ-›ÐÐ
­ÚÐ-œÐÐ
­ÚÐ-ÐÐ
­ÚÐ-žÐÐ
­ÚÐ-ŸÐÐ
­ÚÐ- ÐÐ
­ÚÐ-¡ÐÐ
­ÚÐ-¢ÐÐ
­ÚÐ-£ÐÐ
­	ÚÐ-¤ÐÐ
­
-ÚÐ-¥ÐÐ
­ÚÐ-¦ÐÐ
­ÚÐ-§ÐÐ
­
ÚÐ-¨ÐÐ
­ÚÐ-¢ÐÐ
­ÚÐ-©ÐÐ
­ÚÐ-ªÐÐ
­ÚÐ-«ÐÐ
­ÚÐ-¬ÐÐ
­ÚÐ-­ÐÐ
­ÚÐ-®ÐÐ
­ÚÐ-¯ÐÐ
­ÚÐ-°ÐÐ
­ÚÐ-±ÐÐ
­ÚÐ-²ÐÐ
­ÚÐ-³ÐÐ
­ÚÐ-´ÐÐ
­ÚÐ-µÐÐ
­ÚÐ-¶ÐÐ
­ÚÐ-·ÐÐ
­ÚÐ-¸ÐÐ
­ÚÐ-¹ÐÐ
­ ÚÐ-ºÐÐ
­!ÚÐ-»ÐÐ
­"ÚÐ-¼ÐÐ
­#ÚÐ-½ÐÐ
­$ÚÐ-¾ÐÐ
­%ÚÐ-¿ÐÐ
­&ÚÐ-ÀÐÐ
­'ÚÐ-ÁÐÐ
­(ÚÐ-ÂÐÐ
­)ÚÐ-ÃÐÐ
­*ÚÐ-ÄÐÐ
­+ÚÐ-ÅÐÐ
­,ÚÐ-ÆÐÐ
­7ÚÐ-ÇÐÐ
­8ÚÐ-ÈÐÐ
­9ÚÐ-ÉÐÐ
­:ÚÐ-ÊÐÐ
­;ÚÐ-ËÐÐ
­?ÚÐ-ÌÐÐ
­@ÚÐ-ÍÐÐ
­AÚÐ-ÎÐÐ
­BÚÐ-ÏÐÐ
­kÚÐ-¢ÐÐ-ÑÐÒÓ-ÔÕÖÐ×Ø­
\ No newline at end of file
+Gx_lt!0…jüo4\ø]T̬Z@±System.StringL{6f9dac99-8de1-4efc-8465-68ac443b7d08}SpecialFuncL{0db3d7bb-cde0-4416-9a7b-ce49a0124323}NoneImplementationL{3b83b776-fb25-43b8-99f2-3c507c9143fc}TextDocument	L{f3878285-8e4f-490b-bb1b-9acbb7eb04db}
+TextLinesL{a5de0b0b-1cb5-4913-ac21-9d70293ec00d}Id
longTagText// Componentsn_MQTT.IASyncPropertyProvider( IASyncPropertyProvider );b_MQTT.ITLSContextProvider( ITLSContextProvider );_MQTT();¸Connected := (NOT _MQTT.ClientError() AND NOT _MQTT.IsConnecting() AND _MQTT.IsConnected());b_SparkplugB( AllmetricsList := _AllMetricsList );RIF _MQTT.SubscriberMessageReceived() THENà    _RecvMesg REF= _MQTT.GetSubscriberMessage(MetricList := THIS^._AllMetricsList, MessageTopic => _RecvTopic );l    //onSubscribeMessage( pTopic := ADR( _RecvTopic ),d    //                    pMessage := _RecvMesg );‚    _TopicParser( pTopic := ADR(_RecvTopic) ); //parses the topic    ~    WriteDeviceLog( UDINT_TO_DWORD( CmpLog.LogClass.LOG_INFO ),j                    'PrimaryHost Received Topic: %s',x                    TO_STRING( _TopicParser.MessageType ) ); z    CASE _TopicParser.MessageType OF  //SparkplugMessageTypes!š        SparkplugMessageTypes.NBIRTH: //Birth certificate for MQTT EoN nodes."            _MyEdge REF= THIS^.GetEdge( GroupId := _TopicParser.GroupId,#Œ                                        EdgeId := _TopicParser.EdgeId,$„                                        eError => _HandledError );%B            CASE _HandledError OF&p                ERROR.GroupIDNotFound: // ==> NEW GROUP!'°                    _MyGroupId REF= THIS^.allocGroupId( GroupId := _TopicParser.GroupId,(–                                                        eError => eError );)f                    IF eError = ERROR.NO_ERROR THEN*º                        _MyEdge REF= THIS^.allocEdgetoGroupId( EdgeId := _TopicParser.EdgeId,+Æ                                                               itfGroupID := _MyGroupId.itfGroupID,,¤                                                               eError => eError );-n                        IF eError = ERROR.NO_ERROR THEN.–                            _MyEdge.ProcessNBIRTH( itfPrimaryHost := THIS^,/’                                                   pMessage := _RecvMesg,0ˆ                                                   xError => xError,1Œ                                                   eError => eError );28                        ELSE3V                            xError := TRUE;4^                            //eError := eError;5<                        END_IF60                    ELSE7N                        xError := TRUE;8V                        //eError := eError;94                    END_IF:l                ERROR.EdgeIDNotFound: // ==> NEW EDGE!;¬                    _MyGroupId REF= THIS^.GetGroupID( GroupId := _TopicParser.GroupId,<’                                                      eError => eError );=v                ERROR.NO_ERROR: // ==> UPDATE EXISTING EDGE>†                    _MyEdge.ProcessNBIRTH( itfPrimaryHost := THIS^,?‚                                           pMessage := _RecvMesg,@x                                           xError => xError,A|                                           eError => eError );B             ELSECz                ; //{info 'TODO: maybe some sort of error??'}D(            END_CASEE            Fr        SparkplugMessageTypes.NDATA: //Node data message.G„                    _MyEdge.ProcessNDATA( itfPrimaryHost := THIS^,H€                                          pMessage := _RecvMesg,Iv                                          xError => xError,Jz                                          eError => eError );K>                xError := TRUE;L^                eError := Error.MetricNotFound;M–                WriteDeviceLog( UDINT_TO_DWORD( CmpLog.LogClass.LOG_INFO ),Nš                                'PrimaryHost process NDATA metric error: %s',O~                                TO_STRING( _HandledError ) );  Pb            END_CASE                             Qš        SparkplugMessageTypes.NDEATH: //Death certificate for MQTT EoN nodes.R’                ERROR.NO_ERROR: // ==> UPDATE EXISTING EDGE              SX                    _MyEdge.ProcessNDEATH();T~                eError := Error.OhMy_ThatShouldNotHaveHappened;Uœ                                'PrimaryHost process NDEATH metric error: %s',V*            END_CASE W        XŠ        SparkplugMessageTypes.DBIRTH: //Birth certificate forDevices.Y˜            _MyDevice REF= THIS^.GetDevice( GroupId := _TopicParser.GroupId,Z”                                            EdgeId := _TopicParser.EdgeId,[œ                                            DeviceId := _TopicParser.DeviceId,\Œ                                            eError => _HandledError );]ž                ERROR.GroupIDNotFound:  // ==> NEW GROUP! must rebirth the edge^œ                ERROR.EdgeIDNotFound:   // ==> NEW EDGE! must rebirth the edge_t                ERROR.DeviceIDNotFound: // ==> NEW DEVICE!`Š                ERROR.NO_ERROR:         // ==> UPDATE EXISTING DEVICEa”        SparkplugMessageTypes.DDEATH,    //Death certificate for Devices. b€            SparkplugMessageTypes.DDATA: //Device data message. cV            eError := ERROR.NotImplemented;d€        SparkplugMessageTypes.NCMD,      //Node command message.e„            SparkplugMessageTypes.DCMD,  //Device command message.fš            SparkplugMessageTypes.STATE: //Critical application state messageg†            ;                            //do nothing, ignore theseh    ELSEij        ; //{info 'TODO: maybe some sort of error??'}j    END_CASEk  lEND_IFmv_ExponentialBackOff( Enable := (Connect AND NOT Connected),nn                     ConnectionTime := _ConnectionTime,on                     LockTimesArray := _LockTimesArray,pR                     Enabled => _Enabled,qv                     OutTimeRemaining => _OutTimeRemaining,r~                     LockTimeRemaining => _LockTimeRemaining );sd_StateMachine( Connect := _ExponentialBackOff.out,tb               PrimaryHostConnected := Connected,uJ               pMQTT := ADR( _MQTT ),vb               pSparkplugB := ADR( _SparkplugB ),wH               pPrimaryHost := THIS,x\               SessionState => SessionState );yDiag();zInterface{L{a9ed5b7e-75c5-4651-af16-d2c27e98cb94}|(*}*    Primary Host Node~Ö    Allows you to concenrate Edge of Network Data sent by various Edges or other Sparkplug compatible nodes*)€0{attribute 'reflection'}jFUNCTION_BLOCK FB_PrimaryHost IMPLEMENTS IPrimaryHost‚VAR_INPUTƒ€    ServerUrl     : STRING;          // eg:'test.mosquitto.org';„`    ServerPort    : UINT    := 1883; // eg: 1883…r    PrimaryHostID : WSTRING := "";   // eg:'PrimaryHost';†ˆ    KeepAlive     : UINT    := 60;   // eg: 60 (Value is in seconds)‡V    // Persistent Session (FALSE = DEFAULT)ˆ°    //  * The client must get all messages from a certain topic, even if it is offline. ‰ò    //  * You want the broker to queue the messages for the client and deliver them as soon as the client is back online.ŠX    //  * The client has limited resources. ‹ˆ    //  * You want the broker to store the subscription information of the client and restore the interrupted communication quickly.ŒÈ    //  * The client needs to reNumberOfMetricse all QoS 1 and 2 publish messages after a reconnect.    //  Ž8    //  Clean session (TRUE)à    //  * The client needs only to publish messages to topics, the client does not need to subscribe to topics. Þ    //  * You don t want the broker to store session information or retry transmission of QoS 1 and 2 messages.‘–    //  * The client does not need to get messages that it misses offline. ’    //“H    CleanSession : BOOL    := FALSE;”¦    Username     : WSTRING := "";           // specify a username if any (optional)•¾    Password     : WSTRING := "";           // specify the password for the username (optional)–º    UseTLS       : BOOL;                    // Enables usage of the TLS encryption (optional)—T    hCert        : SysTypes.RTS_IEC_HANDLE˜ü    ;                                           // Handle to the client certificate (optional) and only used if UseTLS is TRUE™\    ITLSContextProvider : MQTT.NBS.ITLSContextš¢    ; //Encapsulates all the data neccessaray to handle encrypted tcp connections›ˆ    //Static initialization, as shown in the following code snippet;œ    //VARV    //    commonName : STRING := 'MyRasPi';ž¸    //    ciCertInfo : NBS.CERT_INFO := (psInfo:=ADR(commonName), udiSize:=LEN(commonName));ŸX    //    myTLSContext : NBS.TLSContext := ( `    //        ePurpose:=NBS.PURPOSE.CLIENT_SIDE,¡L    //        sUseCaseName:='NBSTest',¢B    //        sTLSVersion:='1.3',£J    //        ciCertInfo:=ciCertInfo,¤H    //        udiVerificationMode:=2¥    //    );¦    //END_VAR§š    IASyncPropertyProvider : MQTT.NBS.IAsyncProperty; // Runs the connect process in a own background task. Use this property if the connection setup takes longer than one task cycle (e.g. TLS connections)¨END_VAR©VAR_OUTPUTª4    Connected      : BOOL;«^    SessionState   : SparkplugSessionStateType;¬4    xError         : BOOL;­6    eError         : ERROR;®^    itfPrimaryHost : IPrimaryHost := THIS^;    ¯VAR°Ð    _groupIDPool        : List;         // OF FB_GroupID - This is blank groupids for dynamic allocation±v    _EdgePool           : List;         // OF FB_RemoteEdge²z    _DevicePool         : List;         // OF FB_RemoteDevice³z    _MetricPool         : List;         // OF FB_RemoteMetric´¬    _groupIDs           : List;         // OF FB_GroupID - This is groupIDs with namesµ¦    Connect             : BOOL := TRUE; // TRUE: Connects EoN using the configured settings, FALSE: Disconnects EoN from server if it was connected¶¼    _cPrimaryHostID     : WSTRING;   // Corrected PrimaryHostID, contains no illegal chars    ·>    _Enabled            : BOOL;¸P    _ConnectionTime     : TIME := T#30S;¹¨    _LockTimesArray     : ARRAY[1..8] OF TIME := [4(TIME#30S0MS), 2(TIME#1M0S0MS), TIME#2M0S0MS, TIME#4M0S0MS]; // could be made accessible public  ºž    _OutTimeRemaining   : TIME; // Duration of Out Time Period = TRUE remaining»>    _LockTimeRemaining  : TIME;¼¾    _ExponentialBackOff : FB_ExponentialBackOffTimer; // Handles the Exponential Backoff timing½j    _StateMachine       : FB_PrimaryHostStateMachine;¾l    _TopicProvider      : FB_PrimaryHostTopicProvider;¿Z    _MQTT               : FB_PrimaryHostMQTT;ÀT    _MQTT_eError        : MQTT.MQTT_ERROR;Áž    _SparkplugB         : FB_SparkplugBSimple;     // Handles SparkPlugB Stuff š    _AllMetricsList     : LIST;                    // Of FB_HostStorageMetricâ    _Blob               : ARRAY[0..65535] OF BYTE; // buffer for encoded messagesĤ    _BlobSize           : UDINT;                   // current encoded message sizeÅ|    _LastWillQos        : MQTT.MQTT_QOS := MQTT.MQTT_QOS.QoS0;ÆP    _LastWillRetain     : BOOL := FALSE;Ç’    _LastWillTopic      : WSTRING(GC_Sparkplug.supported_string_lengths);Ȫ    _NDEATH             : FB_SparkplugUInt64;    // contains the current NDEATH BDSeqɺ    _NDEATHPayload      : ARRAY[0..255] OF BYTE; // what is the maximum size of this payload?Ê@    _NDEATHPayloadSize  : UDINT;Ë~    _RecvMesg           : REFERENCE TO FB_PayloadSimpleDecoder;Ì’    _RecvTopic          : WSTRING(GC_Sparkplug.supported_string_lengths);Íâ    _HandledError       : ERROR; // an error that will be given back by a function, but we can handle the error. Îd    _MyGroupId          : REFERENCE TO FB_GroupId;Ïj    _MyEdge             : REFERENCE TO FB_RemoteEdge;Ðn    _MyDevice           : REFERENCE TO FB_RemoteDevice;ÑR    _TopicParser        : FB_TopicParser;ÒB    _Diag               : STRING;Ó>    {attribute 'instance-path'}Ô0    {attribute 'noinit'}Õ$    _POU : STRING;Ö"UniqueIdGenerator×2292ØPOULevelÙL{8e575c5b-1d37-49c6-941b-5c0ec7874787}ÚStandardÛ ChildObjectGuidsÜ8System.Collections.ArrayListÝ,AddAttributeSubsequentÞboolÐÐ-ÐÐ	E
+™ÐÐ
­CÚÐ-ÐÐ
­DÚÐ-ÐÐ
­EÚÐ-ÐÐ
­FÚÐ-ÐÐ
­GÚÐ-ÐÐ
­HÚÐ-ÐÐ
­ºÚÐ-ÐÐ
­IÚÐ-ÐÐ
­JÚÐ-ÐÐ
­KÚÐ-ÐÐ
­LÚÐ-ÐÐ
­MÚÐ-ÐÐ
­NÚÐ-ÐÐ
­OÚÐ-ÐÐ
­PÚÐ-ÐÐ
­QÚÐ-ÐÐ
­RÚÐ-ÐÐ
­SÚÐ-ÐÐ
­TÚÐ- ÐÐ
­UÚÐ-!ÐÐ
­VÚÐ-"ÐÐ
­WÚÐ-#ÐÐ
­XÚÐ-$ÐÐ
­ÂÚÐ-ÐÐ
­YÚÐ-%ÐÐ
­ZÚÐ-&ÐÐ
­[ÚÐ-'ÐÐ
­\ÚÐ-(ÐÐ
­]ÚÐ-ÐÐ
­^ÚÐ-)ÐÐ
­_ÚÐ-*ÐÐ
­`ÚÐ-+ÐÐ
­aÚÐ-,ÐÐ
­bÚÐ-ÐÐ
­cÚÐ--ÐÐ
­dÚÐ-.ÐÐ
­eÚÐ-/ÐÐ
­fÚÐ-0ÐÐ
­gÚÐ-1ÐÐ
­hÚÐ-2ÐÐ
­iÚÐ-3ÐÐ
­jÚÐ-4ÐÐ
­kÚÐ-5ÐÐ
­lÚÐ-6ÐÐ
­mÚÐ-7ÐÐ
­nÚÐ-8ÐÐ
­oÚÐ-9ÐÐ
­pÚÐ-:ÐÐ
­qÚÐ-;ÐÐ
­rÚÐ-<ÐÐ
­sÚÐ-ÐÐ
­tÚÐ-)ÐÐ
­uÚÐ-*ÐÐ
­vÚÐ-+ÐÐ
­wÚÐ-,ÐÐ
­xÚÐ-ÐÐ
­yÚÐ--ÐÐ
­zÚÐ-.ÐÐ
­{ÚÐ-/ÐÐ
­|ÚÐ-0ÐÐ
­}ÚÐ-1ÐÐ
­~ÚÐ-2ÐÐ
­ÚÐ-3ÐÐ
­€ÚÐ-4ÐÐ
­ÚÐ-5ÐÐ
­‚ÚÐ-6ÐÐ
­ƒÚÐ-7ÐÐ
­„ÚÐ-8ÐÐ
­…ÚÐ-9ÐÐ
­†ÚÐ-=ÐÐ
­‡ÚÐ->ÐÐ
­ˆÚÐ-?ÐÐ
­‰ÚÐ-@ÐÐ
­ŠÚÐ-AÐÐ
­‹ÚÐ-BÐÐ
­ŒÚÐ-CÐÐ
­ÚÐ-DÐÐ
­ÃÚÐ-EÐÐ
­¾ÚÐ-FÐÐ
­ÄÚÐ-"ÐÐ
­ÅÚÐ-#ÐÐ
­ÀÚÐ-$ÐÐ
­ÇÚÐ-%ÐÐ
­ÍÚÐ-=ÐÐ
­ÎÚÐ-GÐÐ
­ÏÚÐ-HÐÐ
­ÐÚÐ-IÐÐ
­ÑÚÐ-JÐÐ
­ÒÚÐ-BÐÐ
­ÕÚÐ-KÐÐ
­ÖÚÐ-LÐÐ
­×ÚÐ-MÐÐ
­ØÚÐ-NÐÐ
­ÓÚÐ-OÐÐ
­ÈÚÐ-PÐÐ
­ôÚÐ-ÐÐ
­ŽÚÐ-QÐÐ
­ÜÚÐ-"ÐÐ
­ÝÚÐ-#ÐÐ
­ÞÚÐ-$ÐÐ
­ßÚÐ-%ÐÐ
­íÚÐ-RÐÐ
­áÚÐ-SÐÐ
­åÚÐ-BÐÐ
­æÚÐ-KÐÐ
­çÚÐ-TÐÐ
­èÚÐ-MÐÐ
­éÚÐ-UÐÐ
­êÚÐ-OÐÐ
­ÙÚÐ-VÐÐ
­ÚÐ-WÐÐ
­ÚÐ-XÐÐ
­‘ÚÐ-YÐÐ
­’ÚÐ-ZÐÐ
­“ÚÐ-[ÐÐ
­”ÚÐ-\ÐÐ
­•ÚÐ-ÐÐ
­–ÚÐ-%ÐÐ
­—ÚÐ-]ÐÐ
­˜ÚÐ-^ÐÐ
­™ÚÐ-_ÐÐ
­šÚÐ-`ÐÐ
­›ÚÐ-BÐÐ
­œÚÐ-CÐÐ
­ÚÐ-DÐÐ
­žÚÐ-aÐÐ
­ ÚÐ-bÐÐ
­¡ÚÐ-cÐÐ
­¢ÚÐ-dÐÐ
­£ÚÐ-eÐÐ
­¤ÚÐ-fÐÐ
­¥ÚÐ-gÐÐ
­¦ÚÐ-hÐÐ
­§ÚÐ-iÐÐ
­¨ÚÐ-jÐÐ
­©ÚÐ-kÐÐ
­ªÚÐ-lÐÐ
­«ÚÐ-ÐÐ
­¬ÚÐ-mÐÐ
­­ÚÐ-nÐÐ
­®ÚÐ-oÐÐ
­¯ÚÐ-pÐÐ
­°ÚÐ-qÐÐ
­±ÚÐ-rÐÐ
­²ÚÐ-ÐÐ
­³ÚÐ-sÐÐ
­´ÚÐ-tÐÐ
­µÚÐ-uÐÐ
­¶ÚÐ-vÐÐ
­·ÚÐ-wÐÐ
­¸ÚÐ-xÐÐ
­¹ÚÐ-ÐÐ
­…ÚÐ-yÐz{Ð	E
+]ÐÐ
­ÚÚÐ-|ÐÐ
­ÛÚÐ-}ÐÐ
­ÜÚÐ-~ÐÐ
­ÝÚÐ-ÐÐ
­ÞÚÐ-€ÐÐ
­ßÚÐ-ÐÐ
­àÚÐ-‚ÐÐ
­áÚÐ-ƒÐÐ
­âÚÐ-„ÐÐ
­ãÚÐ-…ÐÐ
­äÚÐ-†ÐÐ
­åÚÐ-‡ÐÐ
­æÚÐ-ˆÐÐ
­çÚÐ-‰ÐÐ
­èÚÐ-ŠÐÐ
­éÚÐ-‹ÐÐ
­êÚÐ-ŒÐÐ
­ëÚÐ-ÐÐ
­ìÚÐ-ŽÐÐ
­íÚÐ-ÐÐ
­îÚÐ-ÐÐ
­ïÚÐ-‘ÐÐ
­ðÚÐ-’ÐÐ
­ñÚÐ-“ÐÐ
­òÚÐ-”ÐÐ
­óÚÐ-•ÐÐ
­ôÚÐ-–ÐÐ
­õÚÐ-—ÐÐ
­öÚÐ-˜ÐÐ
­÷ÚÐ-™ÐÐ
­øÚÐ-šÐÐ
­ùÚÐ-›ÐÐ
­úÚÐ-’ÐÐ
­ûÚÐ-œÐÐ
­üÚÐ-ÐÐ
­ýÚÐ-žÐÐ
­þÚÐ-ŸÐÐ
­ÿÚÐ- ÐÐ
­ÚÐ-¡ÐÐ
­ÚÐ-¢ÐÐ
­ÚÐ-£ÐÐ
­ÚÐ-¤ÐÐ
­ÚÐ-¥ÐÐ
­ÚÐ-¦ÐÐ
­ÚÐ-§ÐÐ
­ÚÐ-¨ÐÐ
­ÚÐ-©ÐÐ
­	ÚÐ-ªÐÐ
­
+ÚÐ-«ÐÐ
­ÚÐ-¬ÐÐ
­ÚÐ-­ÐÐ
­
ÚÐ-®ÐÐ
­ÚÐ-¨ÐÐ
­ÚÐ-¯ÐÐ
­ÚÐ-°ÐÐ
­ÚÐ-±ÐÐ
­ÚÐ-²ÐÐ
­ÚÐ-³ÐÐ
­ÚÐ-´ÐÐ
­ÚÐ-µÐÐ
­ÚÐ-¶ÐÐ
­ÚÐ-·ÐÐ
­ÚÐ-¸ÐÐ
­ÚÐ-¹ÐÐ
­ÚÐ-ºÐÐ
­ÚÐ-»ÐÐ
­ÚÐ-¼ÐÐ
­ÚÐ-½ÐÐ
­ÚÐ-¾ÐÐ
­ÚÐ-¿ÐÐ
­ ÚÐ-ÀÐÐ
­!ÚÐ-ÁÐÐ
­"ÚÐ-ÂÐÐ
­#ÚÐ-ÃÐÐ
­$ÚÐ-ÄÐÐ
­%ÚÐ-ÅÐÐ
­&ÚÐ-ÆÐÐ
­'ÚÐ-ÇÐÐ
­(ÚÐ-ÈÐÐ
­)ÚÐ-ÉÐÐ
­*ÚÐ-ÊÐÐ
­+ÚÐ-ËÐÐ
­,ÚÐ-ÌÐÐ
­7ÚÐ-ÍÐÐ
­8ÚÐ-ÎÐÐ
­9ÚÐ-ÏÐÐ
­:ÚÐ-ÐÐÐ
­;ÚÐ-ÑÐÐ
­?ÚÐ-ÒÐÐ
­@ÚÐ-ÓÐÐ
­AÚÐ-ÔÐÐ
­BÚÐ-ÕÐÐ
­kÚÐ-¨ÐÖ-×ÐØÙ-ÚÛÜÐÝÞ­
\ No newline at end of file