Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NBIRTH into Ignition #5

Closed
MRIIOT opened this issue Sep 29, 2021 · 20 comments
Closed

NBIRTH into Ignition #5

MRIIOT opened this issue Sep 29, 2021 · 20 comments
Assignees
Labels
question Further information is requested

Comments

@MRIIOT
Copy link

MRIIOT commented Sep 29, 2021

Great work on the library! Have you gotten a clean NBIRTH into Ignition? I am running into Ignition throwing exceptions and will be investigating why that is. Will keep you updated.

@MRIIOT
Copy link
Author

MRIIOT commented Sep 30, 2021

I can confirm everything works as expected so far.

Encountered issue is Cirrus Link specific: https://forum.cirrus-link.com/t/topic-segment-group-id-fails-to-parse/126/2

@MRIIOT MRIIOT closed this as completed Sep 30, 2021
@SeppPenner SeppPenner self-assigned this Sep 30, 2021
@SeppPenner SeppPenner added the question Further information is requested label Sep 30, 2021
@SeppPenner
Copy link
Owner

Can you give me some hints on how I can test this with Ignition? I have tried, but honestly didn't understand how Ignition works properly :D

@MRIIOT
Copy link
Author

MRIIOT commented Oct 1, 2021

Sure.

  1. Install Ignition. https://inductiveautomation.com/downloads/ignition/8.1.10

  2. Install CirrusLink modules. https://inductiveautomation.com/downloads/third-party-modules/8.1.10

  • MQTT Distributor Module
  • MQTT Engine Module
  • MQTT Transmission Module
  • MQTT Recorder Module
  1. Log into the gateway. :8088
  2. Activate 2 hour trial
  3. Configure MQTT Engine. https://docs.chariot.io/display/CLD79/ME:+Configuration

You should be able to connect to :1883 MQTT broker.
You should also be able to send SpB payloads.

If you would like, we can get on a call and go through it.

-chris

@MRIIOT
Copy link
Author

MRIIOT commented Jan 13, 2023

Reopening this as it is related.

Observation on a working SpB NBIRTH from Ignition built-in example where seq=0.

On topic=spBv1.0/My MQTT Group/NBIRTH/Edge Node f9ace0: Incoming payload: SparkplugBPayload [timestamp=1673650361762, metrics=[Metric [name=Node Control/Next Server, alias=null, timestamp=1673650361763, dataType=Boolean, isHistorical=null, isTransient=null, metaData=null, properties=null, value=false, isNull=false], Metric [name=Node Info/Transmission Version, alias=null, timestamp=1673650361763, dataType=String, isHistorical=null, isTransient=null, metaData=null, properties=null, value=4.0.12 (b2022072818), isNull=false], Metric [name=bdSeq, alias=null, timestamp=1673650361762, dataType=Int64, isHistorical=null, isTransient=null, metaData=null, properties=null, value=0, isNull=false], Metric [name=Node Control/Rebirth, alias=null, timestamp=1673650361763, dataType=Boolean, isHistorical=null, isTransient=null, metaData=null, properties=null, value=false, isNull=false]], seq=0, uuid=null, body=null]
Processing NBIRTH from Edge Node My MQTT Group/Edge Node f9ace0 with Seq# 0

Here is an example of non-working SpB NBIRTH from custom client using SparkplugbNet 1.2.0 where seq=null.

On topic=spBv1.0/fanuc/NBIRTH/CSC-PF1D271K_f_sim_spb_long: Incoming payload: SparkplugBPayload [timestamp=1673650953121, metrics=[Metric [name=IpAddress, alias=null, timestamp=null, dataType=String, isHistorical=null, isTransient=null, metaData=null, properties=null, value=10.1.10.206;127.0.0.1, isNull=false], Metric [name=BDSEQ, alias=null, timestamp=null, dataType=Int64, isHistorical=null, isTransient=null, metaData=null, properties=null, value=0, isNull=false]], seq=null, uuid=null, body=null]
Invalid payload missing sequence number: spBv1.0/fanuc/NBIRTH/CSC-PF1D271K_f_sim_spb_long

However the same message decoded in MQTT.fx shows seq=0:

{"timestamp":1673650953121,"metrics":[{"name":"IpAddress","dataType":"String","value":"10.1.10.206;127.0.0.1"},{"name":"BDSEQ","dataType":"Int64","value":0}],"seq":0}

Here is a recent topic on the issue: https://forum.cirrus-link.com/t/nbirth-keeps-getting-rejected-for-missing-sequence/244

The SparkplugNet package is using ProtoBuf version 3, which uses the “surpress default values” feature, while the .proto definition specifies version 2, which does not.

I can confirm this observation with Wireshark.

Here is a message where seq>0.
with_seq

Here is the NBIRTH.
no_seq

@MRIIOT
Copy link
Author

MRIIOT commented Feb 3, 2023

The SparkplugNet package is using ProtoBuf version 3, which uses the “surpress default values” feature, while the .proto definition specifies version 2, which does not.

protocolbuffers/protobuf#1606

eclipse-tahu/tahu#260

@SeppPenner does this mean that the proto file needs to be updated? And if so, then that means that SpB spec needs to be updated to pb3.

@Kvargefar
Copy link

Hi,
I've also encountered this issue. After a lot of troubleshooting, I'm struggling to find any other reason why Ignition rejects NBIRTH each time, other than this.

@MRIIOT
Copy link
Author

MRIIOT commented Feb 7, 2023

I'm looking back at the change logs and it looks like protobuf-net 3.0.73+ has been used since February 16, 2021.

I guess my next step is to start downgrading and see when things actually break in Ignition.

https://github.com/SeppPenner/SparkplugNet/tags

@MRIIOT
Copy link
Author

MRIIOT commented Feb 8, 2023

Went to 1.0.0 but ran into a null reference with LWT message UserProperties.
Tried going back to 0.7.0, but required that I downgrade MQTTnet to 3 and I can't do that.
I'll pull the source next.

@MRIIOT
Copy link
Author

MRIIOT commented Feb 8, 2023

Ok that was pretty simple after getting lost for a couple hours.

image

[global::ProtoBuf.ProtoMember(3, Name = @"seq")]
public ulong Seq { get; set; }

Has to include IsRequired = true.

[global::ProtoBuf.ProtoMember(3, Name = @"seq", IsRequired = true)]
public ulong Seq { get; set; }

https://code.google.com/archive/p/protobuf-net/wikis/Attributes.wiki

Any side effects anyone can think of?

using SparkplugNet.Core.Node;
using SparkplugNet.VersionB;
using SparkplugNet.VersionB.Data;

Console.WriteLine("node create");

var nodeMetrics = new List<Metric>
{
    new()
    {
        Name = "IAmNode", DataType = DataType.Boolean,
        BooleanValue = true
    }
};

var node = new SparkplugNode(nodeMetrics, null);

var nodeOptions = new SparkplugNodeOptions(
    brokerAddress: "10.1.10.2",
    port: 1883,
    userName: "admin",
    clientId: Guid.NewGuid().ToString(),
    password: "password",
    useTls: false,
    scadaHostIdentifier: "scada",
    groupIdentifier: "WeProduce",
    edgeNodeIdentifier: "Data",
    reconnectInterval: TimeSpan.FromSeconds(30),
    webSocketParameters: null,
    proxyOptions: null,
    cancellationToken: new CancellationToken()
);

nodeOptions.AddSessionNumberToDataMessages = true;

// ReSharper disable once UnusedParameter.Local
node.DisconnectedAsync += async args =>
{
    Console.WriteLine("node disconnected");
};

// ReSharper disable once UnusedParameter.Local
node.NodeCommandReceivedAsync += async args =>
{
    Console.WriteLine("node command received");
};

node.StatusMessageReceivedAsync += async args =>
{
    Console.WriteLine("node status message received");
};

Console.WriteLine("node birth");

await node.Start(nodeOptions);
await node.PublishMetrics(nodeMetrics);

Console.WriteLine("device create");

var deviceMetrics = new List<Metric>
{
    new()
    {
        Name = "IAmDevice", DataType = DataType.Int32,
        IntValue = 0
    }
};

await node.PublishDeviceBirthMessage(deviceMetrics, "AtTheEdge");

Console.WriteLine("make data forever");

while (true)
{
    await Task.Delay(1000);
    nodeMetrics[0].IntValue += 1;
    await node.PublishDeviceData(deviceMetrics, "AtTheEdge");
}

@Kvargefar
Copy link

Kvargefar commented Feb 8, 2023

@MRIIOT did the isRequired flag help you?
I tried, but didn't find any difference in Ignition.
Which protobuf-net version are you using. Other packages that aren't latest?

After closer inspection, I can see that all my payloads are accepted, except the NBIRTH. This is the first message and seq=0. Looking at the parsed result in Ignition, I can now see that seq=null. Not sure why. I've been testing different methods, but cannot a solution yet. Other clients read the first seq value as 0.

image

Edit: I now see your mentioned issue. These are probably related.

@MRIIOT
Copy link
Author

MRIIOT commented Feb 8, 2023

@MRIIOT did the isRequired flag help you?

I tried, but didn't find any difference in Ignition.

Which protobuf-net version are you using. Other packages that aren't latest?

I did update protobuf-net to latest.

Did you add the parameter to the correct seq?

@Kvargefar
Copy link

Kvargefar commented Feb 8, 2023

It worked.

Added it to the wrong payload. I had two windows.

Will test more. Thank you so much @MRIIOT :)

@MRIIOT
Copy link
Author

MRIIOT commented Feb 8, 2023

I did the same :)

@MRIIOT
Copy link
Author

MRIIOT commented Feb 8, 2023

Once you test, someone should PR.

@SeppPenner
Copy link
Owner

Sorry guys for the late replies. I need to check this (If someone has a clue already if the required flag is used incorrectly somehow), just tell me or add a PR if you want :)

Have been quite busy at work the last weeks...

@MRIIOT
Copy link
Author

MRIIOT commented Feb 21, 2023

(If someone has a clue already if the required flag is used incorrectly somehow), just tell me or add a PR if you want :)

I need to do more testing. I am seeing other fields besides 'seq' causing issues as well.

@SeppPenner
Copy link
Owner

Since Eclipse brought out the TCK kit for testing (3.0 compatibility), I hope to get this done soon and maybe find some more issues as well...

@Kvargefar
Copy link

Been away from this for a couple of weeks now. In regards to publishing/producing, I currently have good results into Ignition after changing the isRequired flag. But I have to do more testing as well.

@Storm-Soft
Copy link

Hi,
first of all thanks for this library development.

I'm also in trouble with the NBIRTH message into ignition.

After reading this exchange I've made the test of setting the "IsRequired" property on sequence as proposed.

[global::ProtoBuf.ProtoMember(3, Name = @"seq", IsRequired = true)]
public ulong Seq { get; set; }

it works like a charm.

@Kvargefar could you make some extra testing and by the way, can you plan a PR ?

Thanks

@SeppPenner
Copy link
Owner

I'm now testing with the official V3.0 TCK, Please follow #39 for updates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants