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

New opc ua client plugin #7213

Closed
wants to merge 14 commits into from
Closed

New opc ua client plugin #7213

wants to merge 14 commits into from

Conversation

fdamador
Copy link

@fdamador fdamador commented Mar 22, 2020

related #3041

Required for all PRs:

  • Signed CLA.
  • Associated README.md updated.
  • Has appropriate unit tests.

@fdamador
Copy link
Author

cannot run dep ensure -add github.com/gopcua/opcua because during dep init throws error on conflicts with github.com/influxdata/go-syslog/v2 packages having problematic subpackages.

Can someone help?

@danielnelson
Copy link
Contributor

Looks like you have it figured out? For that last failing test you need to add github.com/gopcua/opcua to docs/LICENSE_OF_DEPENDENCIES.md

@fdamador
Copy link
Author

fdamador commented Apr 7, 2020

Did you need me to delete the .vscode/launch.json file? I forgot to do that prior to doing a pull request. Also, at what telegraf version will you release this plugin?

@sjwang90 sjwang90 added the area/iot New plugins or features relating to IoT monitoring label Apr 17, 2020
@sjwang90 sjwang90 added this to the 1.15.0 milestone Apr 23, 2020
@jaketimothy
Copy link

Very excited for this. Will see serious use in factory settings. Thank you @fdamador and everyone @gopcua

@MoritzLaut
Copy link

very excited about this too. seems like a lot of users waiting for this plugin!

@qzheng527
Copy link

Yes, looking forward to the final merge to the next release.

@chrishayles
Copy link
Contributor

chrishayles commented May 7, 2020

Currently seeing the following error


panic: runtime error: invalid memory address or nil pointer dereference
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x28 pc=0x178b0a9]

goroutine 66 [running]:
github.com/gopcua/opcua/uasc.(*SecureChannel).setState(0x0, 0x2)
/go/pkg/mod/github.com/gopcua/[email protected]/uasc/secure_channel.go:145 +0x9
panic(0x246b040, 0x4556890)
/usr/local/go/src/runtime/panic.go:679 +0x1b2
github.com/gopcua/opcua/uasc.(*SecureChannel).hasState(...)
/go/pkg/mod/github.com/gopcua/[email protected]/uasc/secure_channel.go:149
github.com/gopcua/opcua/uasc.(*SecureChannel).closeSecureChannel(0x0, 0x0, 0x0)
/go/pkg/mod/github.com/gopcua/[email protected]/uasc/secure_channel.go:744 +0x9e
github.com/gopcua/opcua/uasc.(*SecureChannel).Close(0x0, 0x0, 0x0)
/go/pkg/mod/github.com/gopcua/[email protected]/uasc/secure_channel.go:665 +0x32
github.com/gopcua/opcua.(*Client).Close(0xc000140a00, 0x1b, 0xc000140b00)
/go/pkg/mod/github.com/gopcua/[email protected]/client.go:234 +0x46
github.com/influxdata/telegraf/plugins/inputs/opcua_client.disconnect(0xc00015c000, 0x2ec0bc0, 0xc00004e6a0)
/go/src/github.com/influxdata/telegraf/plugins/inputs/opcua_client/opcua_client.go:352 +0xe7
github.com/influxdata/telegraf/plugins/inputs/opcua_client.(*OpcUA).Gather(0xc00015c000, 0x2f370c0, 0xc0003f7600, 0x0, 0x8)
/go/src/github.com/influxdata/telegraf/plugins/inputs/opcua_client/opcua_client.go:367 +0x37a
github.com/influxdata/telegraf/internal/models.(*RunningInput).Gather(0xc000158320, 0x2f370c0, 0xc0003f7600, 0x2f18020, 0xc0000b4e40)
/go/src/github.com/influxdata/telegraf/internal/models/running_input.go:115 +0x6d
github.com/influxdata/telegraf/agent.(*Agent).gatherOnce.func1(0xc0000b61e0, 0xc000158320, 0x2f370c0, 0xc0003f7600)
/go/src/github.com/influxdata/telegraf/agent/agent.go:336 +0x3f
created by github.com/influxdata/telegraf/agent.(*Agent).gatherOnce
/go/src/github.com/influxdata/telegraf/agent/agent.go:335 +0xf5

When trying to connect to an opc server.

Using OPC simulator:
docker run -dt --name plc -p 50000:50000 mcr.microsoft.com/iotedge/opc-plc:1.0.0-linux-amd64 --autoaccept --unsecuretransport

With Telegraf config:


[global_tags]
dc = "iotedge"

[agent]
interval = "10s"
debug = true

[[outputs.file]]
files = ["stdout"]

[[inputs.opcua_client]]
name = "plc1"
endpoint = "opc.tcp://0.0.0.0:50000"
timeout = 30
security_policy = "None"
security_mode = "None"
nodes = [
{name="SpikeData", namespace="2", identifier_type="s", identifier="SpikeData", data_type="double", description="Randomly generated data"},
]

Telegraf code built and pushed to docker hub here:
chrishaylesnortal/telegraf-demo:1.0.1

@fdamador
Copy link
Author

fdamador commented May 7, 2020

Chris,

I'm not sure your setup enpoint has a valid IP address. Can you try localhost or 127.0.0.1 or the IP address to the container running your OPC UA server.

[[inputs.opcua_client]]
name = "plc1"
> endpoint = "opc.tcp://0.0.0.0:50000"

@chrishayles
Copy link
Contributor

chrishayles commented May 7, 2020

@fdamador

Same result with localhost and 127.0.0.1.

To remove my simulator as a possibility, I tried configuring it to work with a separate KEPWare based simulator, too. Getting the same result there. The Telegraf config I'm using for that:

[global_tags]
dc = "iotedge"

[agent]
interval = "10s"
debug = true

[[outputs.file]]
files = ["stdout"]

[[inputs.opcua_client]]
name = "plc1"
endpoint = "opc.tcp://$IP:49320"
timeout = 60
security_policy = "None"
security_mode = "None"
nodes = [
{name="Tag1Double", namespace="2", identifier_type="s", identifier="SimulationPLC.plugintest.Tag1Double", data_type="double", description=""},
]

@fdamador
Copy link
Author

fdamador commented May 7, 2020

@haylesnortal

Ok, let me review. I was able to replicate your original error. the good news is that I'm able to read the data point using the examples from the gopcua library...so will trace out the bug.

@chrishayles
Copy link
Contributor

chrishayles commented May 7, 2020

@fdamador think I've got it...

  1. the error was to do with the disconnect() call before it was ever connected. Commented that out. I was then able to see the real error: regardless of what endpoint address I gave, the client was trying to connect on 127.0.0.1.

  2. I checked the endpoints being returned by the OPC UA server and 127.0.0.1 is the first of a few. This is pretty common. And not every server will know it's own public facing endpoint.

  3. You were then selecting an endpoint, building out client options from that endpoint (all good up to here) then sending that endpoint.EndpointURL to create the client: o.client = opcua.NewClient(ep.EndpointURL, opts...) ...this being the 127.0.0.1 endpoint.

  4. So I replace this with the original endpoint supplied by the user: o.client = opcua.NewClient(o.Endpoint, opts...)

That seemed to fix it.

@fdamador
Copy link
Author

fdamador commented May 7, 2020

Thanks for help, that did it. I've committed and pushed my changes.

image

@chrishayles
Copy link
Contributor

@fdamador Thanks for taking a look and the quick response. Much appreciated.

@chrishayles
Copy link
Contributor

Still seeing issues... this time, it reads the first value fine, but then it never updates. I can see the OPC sim values changing in my OPC browser, but Telegraf never sees updated values. I think it's because the only call to readvalues() is in the Connect() function. I'll play around with it, see what I can do.

@fdamador
Copy link
Author

fdamador commented May 8, 2020

Understood, I made these modifications. Let me know if this is what you were thinking.

@danielnelson danielnelson modified the milestones: 1.15.0, 1.16.0 Jul 7, 2020
@PWSys
Copy link

PWSys commented Jul 8, 2020

It would be helpful to customize the incoming schema. Examples include adding custom tags and monitoring multiple fields per measurement. There won't always be a 1:1 relationship between a monitored OPC-UA node and the desired measuremnt in InfluxDB.

Copy link
Contributor

@ssoroka ssoroka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the plugin! Have some feedback for you.

@@ -0,0 +1,18 @@
(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't commit these dot-files.

@@ -0,0 +1,6525 @@
# Telegraf Configuration
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be committed.

# # Time Inteval, default = 100 * time.Millisecond
# # interval = "10000000"
#
# # Security policy: None, Basic128Rsa15, Basic256, Basic256Sha256. Default: auto
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default says auto, but text says "None" these should match

### Example Output:

```
$ ./telegraf -config telegraf.conf -input-filter opcua_client -test
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be actual example output, not the command to run to get the output.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an example input/output would be very useful for this README

var err error

o.Name = "testing"
o.Endpoint = "opc.tcp://opcua.rocks:4840"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is hitting a remote service on the internet? can we store and mock the response instead?

TimestampsToReturn: ua.TimestampsToReturnBoth,
}

err = o.getData()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Connect should not call getData, gather already does this.

return err
}

o.ReadError = 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there's any reason to reset these.

switch u.Scheme {
case "opc.tcp":
o.state = Disconnected
o.client.Close()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unset o.client here so you know you need to reconnect. and you can drop o.state.

}

func disconnect(o *OpcUA) error {
u, err := url.Parse(o.Endpoint)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no reason to parse the endpoint or check the scheme here.

}
o.NodeData[i].Quality = d.Status
o.NodeData[i].TimeStamp = d.ServerTimestamp.String()
o.NodeData[i].Time = d.SourceTimestamp.String()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string timestamps are notoriously difficult to work with. Not sure why you'd convert to a string here.

@@ -0,0 +1,57 @@
# Telegraf Input Plugin: opcua_client

The opcua_client plugin retrieves data from OPCUA slave devices
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please replace the term slave with replica, secondary or any of the following suggestions.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks I’ll replace with server to match industry standards nomenclature

@sjwang90
Copy link
Contributor

Hey @fdamador, just checking in on the progress of @ssoroka's suggestions. We'd love to get others to start using this! Thanks again!

@sjwang90
Copy link
Contributor

@fdamador do you think you could test your plugin with the Prosys simulator? Was trying to troubleshoot with @haylesnortal last week and was getting various errors.

2020-07-21T22:16:05Z E! [inputs.opcua_client] Error in plugin: Endpoint Error: opcua: could not resolve address ip-192-168-1-2.ec2.internal:53530

@sjwang90
Copy link
Contributor

sjwang90 commented Sep 8, 2020

Hey @fdamador, we merged in #8009 last week. Wanted to give you a big thanks as your plugin was the base of the final plugin that was merged.

Feel free to test out that new plugin with master or the nightly build.

@sjwang90 sjwang90 closed this Sep 8, 2020
@fdamador
Copy link
Author

fdamador commented Sep 8, 2020

Awesome! Glad I could be of service.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/iot New plugins or features relating to IoT monitoring new plugin
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants