0.01
Low commit activity in last 3 years
No release in over a year
Basic OPC-UA client library for Ruby. Uses open62541 (https://open62541.org) under the hood.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies
 Project Readme

opcua-client-ruby

Incomplete OPC-UA client library for Ruby. Wraps open62541: https://open62541.org.

ci-badge

Installation

Add it to your Gemfile:

gem 'opcua_client'

Basic usage

Use start helper to automatically close connections:

require 'opcua_client'

OPCUAClient.start("opc.tcp://127.0.0.1:4840") do |client|
  # write to ns=2;s=1
  client.write_int16(2, "1", 888)
  puts client.read_int16(2, "1")
end

Or handle connections manually:

require 'opcua_client'

client = OPCUAClient::Client.new
begin
  client.connect("opc.tcp://127.0.0.1:4840")
  # write to ns=2;s=1
  client.write_int16(2, "1", 888)
  puts client.read_int16(2, "1")

  client.multi_write_int16(2, (1..10).map{|x| "action_#{x}"}, (1..10).map{|x| x * 10}) # 10x writes
  client.multi_write_int32(2, (1..10).map{|x| "amount_#{x}"}, (1..10).map{|x| x * 10 + 1}) # 10x writes
ensure
  client.disconnect
end

Available methods - connection:

  • client.connect(String url) - raises OPCUAClient::Error if unsuccessful
  • client.disconnect => Fixnum - returns status

Available methods - reads and writes:

All methods raise OPCUAClient::Error if unsuccessful.

  • client.read_int16(Fixnum ns, String name) => Fixnum
  • client.read_uint16(Fixnum ns, String name) => Fixnum
  • client.read_int32(Fixnum ns, String name) => Fixnum
  • client.read_uint32(Fixnum ns, String name) => Fixnum
  • client.read_float(Fixnum ns, String name) => Float
  • client.read_boolean(Fixnum ns, String name) => true/false
  • client.write_int16(Fixnum ns, String name, Fixnum value)
  • client.write_uint16(Fixnum ns, String name, Fixnum value)
  • client.write_int32(Fixnum ns, String name, Fixnum value)
  • client.write_uint32(Fixnum ns, String name, Fixnum value)
  • client.write_float(Fixnum ns, String name, Float value)
  • client.write_boolean(Fixnum ns, String name, bool value)
  • client.multi_write_int16(Fixnum ns, Array[String] names, Array[Fixnum] values)
  • client.multi_write_uint16(Fixnum ns, Array[String] names, Array[Fixnum] values)
  • client.multi_write_int32(Fixnum ns, Array[String] names, Array[Fixnum] values)
  • client.multi_write_uint32(Fixnum ns, Array[String] names, Array[Fixnum] values)
  • client.multi_write_float(Fixnum ns, Array[String] names, Array[Float] values)
  • client.multi_write_boolean(Fixnum ns, Array[String] names, Array[bool] values)

Available methods - misc:

  • client.state => Fixnum - client internal state
  • client.human_state => String - human readable client internal state
  • OPCUAClient::Client.human_status_code(Fixnum status) => String - returns human status for status

Subscriptions and monitoring

cli = OPCUAClient::Client.new

cli.after_session_created do |cli|
  subscription_id = cli.create_subscription
  ns_index = 1
  node_name = "the.answer"
  cli.add_monitored_item(subscription_id, ns_index, node_name)
end

cli.after_data_changed do |subscription_id, monitor_id, server_time, source_time, new_value|
  puts("data changed: " + [subscription_id, monitor_id, server_time, source_time, new_value].inspect)
end

cli.connect("opc.tcp://127.0.0.1:4840")

loop do
  cli.connect("opc.tcp://127.0.0.1:4840") # no-op if connected
  cli.run_mon_cycle
  sleep(0.2)
end

Available methods:

  • client.create_subscription => Fixnum - nil if error
  • client.add_monitored_item(Fixnum subscription, Fixnum ns, String name) => Fixnum - nil if error
  • client.run_mon_cycle - returns status
  • client.run_mon_cycle! - raises OPCUAClient::Error if unsuccessful

Available callbacks:

  • after_session_created
  • after_data_changed

Contribute

Set up

bundle

Build and start dummy OPCUA server

make -C tools/server/ clean all # clean+all
tools/server/server # run

Try out changes

$ bin/rake compile
$ bin/console
pry> client = OPCUAClient::Client.new
pry> client.connect("opc.tcp://127.0.0.1:4840")
pry> client.read_uint32(5, "uint32b")
pry> client.read_uint16(5, "uint16b")
pry> client.read_bool(5, "true_var")

Test it

$ bin/rake compile
$ bin/rake spec