1 | {"payload":{"meta":{"Graph":{"@Type":"81297157","@Value":{"Guid":"(Guid)af25efb2-e7d3-4d17-9b46-1d6d5c77fe77","ParentGuid":"(Guid)00000000-0000-0000-0000-000000000000","Name":"(string)FB_Edge","Properties":{"@Type":"2c41fa04:IDictionary","@Value":[{"@Key":"(Guid)24568a24-c491-472c-a21f-ee5d33859fab","@Value":{"@Type":"24568a24","@Value":{"MemoryReserveForOnlineChange":"(int)0","ExcludeFromBuild":"(bool)False","External":"(bool)False","EnableSystemCall":"(bool)False","CompilerDefines":"(string)","LinkAlways":"(bool)False","Undefines":{"@Type":"[string]","@Value":[]}}}},{"@Key":"(Guid)829a18f2-c514-4f6e-9634-1df173429203","@Value":{"@Type":"829a18f2","@Value":{"ParentObjects":{"@Type":"fa2ee218:IDictionary","@Value":[{"@Key":"(Guid)21af5390-2942-461a-bf89-951aaf6999f1","@Value":"(Guid)df8b6e33-73a6-4e1c-bc61-8ee3c2cdd757"}]}}}}]},"TypeGuid":"(Guid)6f9dac99-8de1-4efc-8465-68ac443b7d08","EmbeddedTypeGuids":{"@Type":"[Guid]","@Value":["(Guid)a9ed5b7e-75c5-4651-af16-d2c27e98cb94","(Guid)3b83b776-fb25-43b8-99f2-3c507c9143fc"]}}},"TypeInfos":{"24568a24":"{24568a24-c491-472c-a21f-ee5d33859fab}","2c41fa04":"{2c41fa04-1834-41c1-816e-303c7aa2c05b}","81297157":"{81297157-7ec9-45ce-845e-84cab2b88ade}","829a18f2":"{829a18f2-c514-4f6e-9634-1df173429203}","bool":"System.Boolean","fa2ee218":"{fa2ee218-a39b-4b6d-b249-49dbddbd168a}","Guid":"System.Guid","int":"System.Int32","string":"System.String"}},"object":{"Graph":{"@Type":"6f9dac99","@Value":{"SpecialFunc":{"@Type":"0db3d7bb:Enum","@Value":"None"},"Implementation":{"@Type":"3b83b776","@Value":{"TextDocument":{"@Type":"f3878285","@Value":{"TextBlobForSerialisation":"(string)//Make a pointer to avoid warning on external usage of VAR_IN_OUT\n_puiPublishPeriod := ADR( publishPeriod );\n\n// ServiceProviders for MQTT and TLS\n_MQTT.IASyncPropertyProvider( IASyncPropertyProvider );\n_MQTT.ITLSContextProvider( ITLSContextProvider );\n_MQTT();\n\n// ServiceProvider for Sparkplug B Payload Certificates and Encoding / Decoding\n_SparkplugB();\n\nIF _MQTT.STATEMessageReceived() THEN\n _RecvSTATEMesg := _MQTT.GetSTATEMessage( MessageTopic => _RecvSTATETopic );\n onSTATEMessage( Topic := _RecvSTATETopic,\n Message := _RecvSTATEMesg );\nEND_IF\n\nIF _MQTT.NCMDMessageReceived() THEN\n _RecvNCMDMesg REF= _MQTT.GetNCMDMessage( MessageTopic => _RecvNCMDTopic );\n // only updates the received NCMD metric\n onNCMDMessage( pTopic := ADR( _RecvNCMDTopic ), pMessage := _RecvNCMDMesg );\nEND_IF\n\n// Provide Remote Host with all kinds of Info from this edge\n_EdgeInfoProvider( IWantExtendedEdgeInfoPublished := SPStack.GVL_sparkplug.IWantExtendedEdgeInfoPublished, // some parts are opt-out\n AllMetricsList := THIS^._Metrics );\n\n// Provides Remote Host with the Controls this edge supports\n_EdgeControlProvider( AllMetricsList := THIS^._Metrics,\n PublishPeriod := THIS^.publishPeriod,\n Rebirth => _Rebirth );\n\nConnected := ( NOT _MQTT.ClientError() AND NOT _MQTT.IsConnecting() AND _MQTT.IsConnected() ); \n \n// ServiceProvider to handle reconnecta via configurable exponential backoff timer, \n_ExponentialBackOff( Enable := Connect,\n IsConnected := Connected,\n ConnectionTime := _ConnectionTime, // Wait xx time during reconnection phase\n LockTimesArray := _LockTimesArray, // contains the times between reconnection attempt\n IsEnabled => _Enabled, // Feedback Enable\n Q_TimeRemain => _OutTimeRemaining, // time left for current reconnect phase\n LockTimeRemain => _LockTimeRemaining ); // time left for current lockphase (we wait for next reconnect attempt)\n\n// The main Edge State Machine\n_StateMachine( Connect := _ExponentialBackOff.Q, // Reconnect yes/no\n EoNConnected := Connected, // MQTT Client is Connected\n ReBirth := _Rebirth,\n TimeToWait := TO_TIME( publishPeriod ),\n pMQTT := ADR( _MQTT ),\n pSparkplugB := ADR( _SparkplugB ),\n pEdge := THIS,\n AllMetricsList := _Metrics,\n DeviceList := _Devices,\n SessionState => SessionState ); // Our MQTT SessionState\n\n_Rebirth := FALSE;\n\n// update current number of plugged devices\nNumberOfDevices := _Devices.ListSize;\n\nDiag();","LineInfoPersistence":"(string)af25efb2-e7d3-4d17-9b46-1d6d5c77fe77_Impl_LineIds"}}}},"Interface":{"@Type":"a9ed5b7e","@Value":{"TextDocument":{"@Type":"f3878285","@Value":{"TextBlobForSerialisation":"(string)(*\n Edge of Network Node\n Allows you to bidirectionally share sparkplug data from the edge of your network to a Primary Host Node\n*)\n{attribute 'no_assign'}\n{attribute 'reflection'}\nFUNCTION_BLOCK PUBLIC FB_Edge IMPLEMENTS IEdge\nVAR_INPUT\n Connect : BOOL; // TRUE: Connects EoN using the configured settings, FALSE: Disconnects EoN from server if it was connected\n ServerUrl : STRING; // TCP:'test.mosquitto.org' or WebSocket: ‘ws://localhost:8080’ ws-URI = “ws:” “//” host [ ”:” port ] path [ ”?” query ] wss-URI = “wss:” “//” host [ ”:” port ] path [ ”?” query ]\n ServerPort : UINT := 1883; // Only in TCP Mode, eg: 1883\n PingInterval : TIME := T#2S; // Ping interval for TCP and Websocket mode, default interval = T#2s\n CommunicationMode : MQTT.COMMUNICATION_MODE := MQTT.COMMUNICATION_MODE.TCP; // Choose either TCP or WebSockets\n HttpProxySettings : MQTT.WEB_SOCKET.HttpProxySettings; // Contains Proxy- Server, Port, User and Password settings \n PrimaryHostID : WSTRING := \"\"; // eg:'PrimaryHostNode'; \n KeepAlive : UINT := 60; // eg: 60 (Value is in seconds)\n // Persistent Session (FALSE = DEFAULT)\n // * The client must get all messages from a certain topic, even if it is offline. \n // * You want the broker to queue the messages for the client and deliver them as soon as the client is back online.\n // * The client has limited resources. \n // * You want the broker to store the subscription information of the client and restore the interrupted communication quickly.\n // * The client needs to reNumberOfMetricse all QoS 1 and 2 publish messages after a reconnect.\n // \n // Clean session (TRUE)\n // * The client needs only to publish messages to topics, the client does not need to subscribe to topics. \n // * You don’t want the broker to store session information or retry transmission of QoS 1 and 2 messages.\n // * The client does not need to get messages that it misses offline. \n //\n CleanSession : BOOL := FALSE;\n Username : WSTRING := \"\"; // specify a username if any (optional)\n Password : WSTRING := \"\"; // specify the password for the username (optional)\n UseTLS : BOOL; // Enables usage of the TLS encryption (optional)\n hCert : SysTypes.RTS_IEC_HANDLE; // Handle to the client certificate (optional) and only used if UseTLS is TRUE\n GroupId : WSTRING; // eg: \"SparkplugBDevice\"\n NodeName : WSTRING; // eg: \"EoN1\"\n ITLSContextProvider : MQTT.NBS.ITLSContext; //Encapsulates all the data neccessaray to handle encrypted tcp connections\n //Static initialization, as shown in the following code snippet;\n //\n //VAR\n // commonName : STRING := 'MyRasPi';\n // ciCertInfo : NBS.CERT_INFO := (psInfo:=ADR(commonName), udiSize:=LEN(commonName));\n // myTLSContext : NBS.TLSContext := (\n // ePurpose:=NBS.PURPOSE.CLIENT_SIDE,\n // sUseCaseName:='NBSTest',\n // sTLSVersion:='1.3',\n // ciCertInfo:=ciCertInfo,\n // udiVerificationMode:=2\n // );\n //END_VAR\n 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)\n UseAliases : BOOL := TRUE;\nEND_VAR\nVAR_OUTPUT\n Connected : BOOL;\n SessionState : SPStack.SparkplugSessionStateType;\n {attribute 'no_copy'}\n itfEdge : IEdge := THIS^;\n NumberOfDevices : UDINT;\nEND_VAR\nVAR_IN_OUT\n publishPeriod : UINT; // eg: 5000 (Value is in milliseconds), can be altered remotely too\nEND_VAR\nVAR\n _Enabled : BOOL;\n _Rebirth : BOOL;\n _ConnectionTime : TIME := T#30S;\n _LockTimesArray : ARRAY[ 1..8 ] OF TIME := [ 4(TIME#30S0MS), 2(TIME#1M0S0MS), TIME#2M0S0MS, TIME#4M0S0MS ]; // could be made accessible public \n _OutTimeRemaining : TIME; // Duration of Out Time Period = TRUE remaining\n _LockTimeRemaining : TIME; // Duration of Out Time Period = FALSE remaining\n _ExponentialBackOff : SPStack.FB_ExponentialBackOffTimer; // Handles the Exponential Backoff ttiming\n _StateMachine : FB_EdgeStateMachine;\n _TopicProvider : SPStack.FB_EdgeTopicProvider;\n _EdgeInfoProvider : FB_EdgeInfoProvider;\n _EdgeControlProvider : FB_EdgeControlProvider;\n _cPrimaryHostID : WSTRING; // Corrected PrimaryHostID, contains no illegal chars\n _cGroupId : WSTRING; // Corrected GroupId, contains no illegal chars\n _cNodeName : WSTRING; // Corrected NodeName, contains no illegal chars\n _MQTT : FB_EdgeMQTT;\n _MQTT_eError : MQTT.MQTT_ERROR;\n _SparkplugB : SPStack.FB_SparkplugBxCoderHandler; // Handles SparkPlugB Stuff\n _Devices : LinkedList.List; // Handles all connected Devices\n _prevNumberOfDevices : UDINT;\n _ItfCurElement : LinkedList.IElement;\n _DeviceCnt : UDINT;\n _ItfCurDevice : IDevice;\n _HasItfDevice : BOOL;\n _Metrics : LinkedList.List; // Complete List Of All Metrics That Will ever be Sent, needed for NBIRTH \n _ChangeList : LinkedList.List; // The Send list; Needed for NDATA\n _Initialise : BOOL;\n _Disconnect : BOOL;\n _Initialised : BOOL;\n _Reset : BOOL;\n _SubscribeNCMD : BOOL;\n _UnSubscribeNCMD : BOOL;\n _NodeBirthPublished : BOOL;\n _PublishNodeDataStart : BOOL;\n _DisablePublisher : BOOL;\n _LastWillTopic : WSTRING( SPStack.GC_sparkplug.supported_string_lengths );\n _NDEATH : SPStack.FB_Metric; // contains the current NDEATH BDSeq\n _NDEATHPayload : ARRAY[ 0..255 ] OF BYTE; // what is the maximum size of this payload?\n _NDEATHPayloadSize : UDINT;\n _LastWillQos : MQTT.MQTT_QOS := MQTT.MQTT_QOS.QoS0;\n _LastWillRetain : BOOL := FALSE;\n _NBIRTH : SPStack.FB_Metric := ( _dataType := SPStack.MetricDataType.UInt64 ); // contains the current raw NBIRTH seq\n _Blob : ARRAY[ 0..MQTT.MQTTParam.g_udiMaxPayloadSize ] OF BYTE; // buffer for encoded messages\n _BlobSize : UDINT; // current encoded message size\n _NDATAEncoderPrepared : BOOL := FALSE;\n _PublishNDATA : BOOL;\n _ErrorDetected : BOOL;\n _ChangeError : SPStack.ERROR;\n _ChangeDetected : BOOL; // At least 1 Signal change has been detected; RBE needed next PublishInterval \n _CurrentChanges : UDINT; // Number of detected changes, each changes reflects 1 Signal \n _MessageType : SPStack.SparkplugMessageTypes;\n _RecvSTATEMesg : STRING;\n _RecvSTATETopic : WSTRING( SPStack.GC_sparkplug.supported_string_lengths );\n _RecvNCMDMesg : REFERENCE TO SPStack.FB_Payload;\n _RecvNCMDTopic : WSTRING( SPStack.GC_sparkplug.supported_string_lengths );\n _Diag : STRING;\n _puiPublishPeriod : POINTER TO UINT;\n _Alias : ULINT := 1; // 0 is reserved in metrics to flag that no alias has been assigned yet to that metric\n\n // IMessageSource\n _IMessageSource_Device : LinkedList.IElement; //The itfElement that you are publishing (for FB_Edge this will be a FB_Device)\n _IMessageSource_publishing : BOOL;\n _IMessageSource_published : BOOL; // TRUE when publish is complete. Is set false automatically in claimExclusivePublishingRights, but you can set it false yourself if you want\n\n {attribute 'instance-path'}\n {attribute 'noinit'}\n _POU : STRING;\nEND_VAR","LineInfoPersistence":"(string)af25efb2-e7d3-4d17-9b46-1d6d5c77fe77_Decl_LineIds"}}}},"UniqueIdGenerator":"(string)17891","POULevel":{"@Type":"8e575c5b:Enum","@Value":"Standard"},"ChildObjectGuids":{"@Type":"ArrayList:IList","@Value":[]},"AddAttributeSubsequent":"(bool)False"}},"TypeInfos":{"0db3d7bb":"{0db3d7bb-cde0-4416-9a7b-ce49a0124323}","3b83b776":"{3b83b776-fb25-43b8-99f2-3c507c9143fc}","6f9dac99":"{6f9dac99-8de1-4efc-8465-68ac443b7d08}","8e575c5b":"{8e575c5b-1d37-49c6-941b-5c0ec7874787}","a9ed5b7e":"{a9ed5b7e-75c5-4651-af16-d2c27e98cb94}","ArrayList":"System.Collections.ArrayList","bool":"System.Boolean","f3878285":"{f3878285-8e4f-490b-bb1b-9acbb7eb04db}","string":"System.String"}}},"FormatVersion":"1.0"} |