opcua 0.11 → 0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,96 @@
2
2
  VALUE mTYPES = Qnil;
3
3
 
4
4
  /* -- */
5
+ static void variant_set_one_dimension(UA_Variant *variant,UA_UInt32 len) {
6
+ variant->arrayDimensions = (UA_UInt32 *)UA_Array_new(1, &UA_TYPES[UA_TYPES_UINT32]);
7
+ variant->arrayDimensions[0] = len;
8
+ variant->arrayDimensionsSize = 1;
9
+ }
10
+ static bool value_to_array(VALUE value, UA_Variant *variant) {/*{{{*/
11
+ int done = false;
12
+
13
+ if (rb_obj_is_kind_of(RARRAY_AREF(value,0),rb_cTime)) {
14
+ UA_DateTime tmp[RARRAY_LEN(value)];
15
+ for (int i=0; i < RARRAY_LEN(value); i++) {
16
+ if (TYPE(RARRAY_AREF(value,i)) == T_FALSE) {
17
+ tmp[i] = UA_DateTime_fromUnixTime(rb_time_timeval(RARRAY_AREF(value,i)).tv_sec);
18
+ } else {
19
+ tmp[i] = UA_DateTime_fromUnixTime(0);
20
+ }
21
+ }
22
+ variant_set_one_dimension(variant,1);
23
+ UA_Variant_setArrayCopy(variant, tmp, RARRAY_LEN(value), &UA_TYPES[UA_TYPES_BOOLEAN]);
24
+ done = true;
25
+ } else {
26
+ switch (TYPE(RARRAY_AREF(value,0))) {
27
+ case T_TRUE:
28
+ case T_FALSE:
29
+ {
30
+ UA_Boolean tmp[RARRAY_LEN(value)];
31
+ for (int i=0; i < RARRAY_LEN(value); i++) {
32
+ if (TYPE(RARRAY_AREF(value,i)) == T_FALSE) {
33
+ tmp[i] = false;
34
+ } else {
35
+ tmp[i] = true;
36
+ }
37
+ }
38
+ variant_set_one_dimension(variant,1);
39
+ UA_Variant_setArrayCopy(variant, tmp, RARRAY_LEN(value), &UA_TYPES[UA_TYPES_BOOLEAN]);
40
+ done = true;
41
+ break;
42
+ }
43
+ case T_FLOAT:
44
+ case T_FIXNUM:
45
+ {
46
+ UA_Double tmp[RARRAY_LEN(value)];
47
+ for (int i=0; i < RARRAY_LEN(value); i++) {
48
+ if (TYPE(RARRAY_AREF(value,i)) == T_FLOAT || TYPE(RARRAY_AREF(value,i)) == T_FIXNUM) {
49
+ tmp[i] = NUM2DBL(RARRAY_AREF(value,i));
50
+ } else {
51
+ tmp[i] = 0.0;
52
+ }
53
+ }
54
+ variant_set_one_dimension(variant,1);
55
+ UA_Variant_setArrayCopy(variant, tmp, RARRAY_LEN(value), &UA_TYPES[UA_TYPES_DOUBLE]);
56
+ done = true;
57
+ break;
58
+ }
59
+ case T_STRING:
60
+ case T_SYMBOL:
61
+ {
62
+ UA_String tmp[RARRAY_LEN(value)];
63
+ for (int i=0; i < RARRAY_LEN(value); i++) {
64
+ if (TYPE(RARRAY_AREF(value,i)) == T_STRING || TYPE(RARRAY_AREF(value,i)) == T_SYMBOL) {
65
+ VALUE str = rb_obj_as_string(RARRAY_AREF(value,i));
66
+ tmp[i] = UA_STRING(StringValuePtr(str));
67
+ } else {
68
+ tmp[i] = UA_STRING("");
69
+ }
70
+ }
71
+ variant_set_one_dimension(variant,1);
72
+ UA_Variant_setArrayCopy(variant, tmp, RARRAY_LEN(value), &UA_TYPES[UA_TYPES_STRING]);
73
+ done = true;
74
+ break;
75
+ }
76
+ //////// TODO Currently only one-dimensional data structures are supported
77
+ // case T_ARRAY:
78
+ // {
79
+ // UA_Variant xxx;
80
+ // for (int i=0; i < RARRAY_LEN(value); i++) {
81
+ // for (int j=0; j < RARRAY_LEN(RARRAY_AREF(value,0)); j++) {
82
+ // if (j < RARRAY_LEN(RARRAY_AREF(value,i)) {
83
+ // } else {
84
+ // }
85
+ // }
86
+ // }
87
+ // UA_Variant_setArrayCopy(variant, tmp, RARRAY_LEN(value) * RARRAY_LEN(RARRAY_AREF(value,0)), &UA_TYPES[UA_TYPES_STRING]);
88
+ // done = true;
89
+ // break;
90
+ // }
91
+ }
92
+ }
93
+ return done;
94
+ }/*}}}*/
5
95
  static bool value_to_variant(VALUE value, UA_Variant *variant) { //{{{
6
96
  bool done = false;
7
97
  if (rb_obj_is_kind_of(value,rb_cTime)) {
@@ -36,8 +126,6 @@ static bool value_to_variant(VALUE value, UA_Variant *variant) { //{{{
36
126
  case T_SYMBOL:
37
127
  {
38
128
  VALUE str = rb_obj_as_string(value);
39
- if (NIL_P(str) || TYPE(str) != T_STRING)
40
- rb_raise(rb_eTypeError, "cannot convert obj to string");
41
129
  UA_String tmp = UA_STRING(StringValuePtr(str));
42
130
  UA_Variant_setScalarCopy(variant, &tmp, &UA_TYPES[UA_TYPES_STRING]);
43
131
  done = true;
@@ -45,11 +133,10 @@ static bool value_to_variant(VALUE value, UA_Variant *variant) { //{{{
45
133
  }
46
134
  case T_ARRAY:
47
135
  {
48
- // UA_UInt32 arrayDims = 0;
49
- // attr.valueRank = UA_VALUERANK_ONE_DIMENSION;
50
- // attr.arrayDimensions = &arrayDims;
51
- // attr.arrayDimensionsSize = 1;
52
- // UA_Variant_setArray(&attr.value, UA_Array_new(10, &UA_TYPES[type]), 10, &UA_TYPES[type]);
136
+ if (value_to_array(value,variant)) {
137
+ done = true;
138
+ }
139
+ break;
53
140
  }
54
141
  }
55
142
  }
@@ -69,45 +156,123 @@ static void Init_types() {/*{{{*/
69
156
  rb_define_const(mTYPES, "STRING", INT2NUM(UA_TYPES_STRING ));
70
157
  }/*}}}*/
71
158
 
159
+ static VALUE UA_TYPES_DATETIME_to_value(UA_DateTime data) {
160
+ return rb_time_new(UA_DateTime_toUnixTime(data),0);
161
+ }
162
+ static VALUE UA_TYPES_BOOLEAN_to_value(UA_Boolean data) {
163
+ return data ? Qtrue : Qfalse;
164
+ }
165
+ static VALUE UA_TYPES_DOUBLE_to_value(UA_Double data) {
166
+ return DBL2NUM(data);
167
+ }
168
+ static VALUE UA_TYPES_INT32_to_value(UA_Int32 data) {
169
+ return INT2NUM(data);
170
+ }
171
+ static VALUE UA_TYPES_INT16_to_value(UA_Int16 data) {
172
+ return INT2NUM(data);
173
+ }
174
+ static VALUE UA_TYPES_UINT32_to_value(UA_UInt32 data) {
175
+ return UINT2NUM(data);
176
+ }
177
+ static VALUE UA_TYPES_UINT16_to_value(UA_UInt16 data) {
178
+ return UINT2NUM(data);
179
+ }
180
+ static VALUE UA_TYPES_STRING_to_value(UA_String data) {
181
+ return rb_str_export_locale(rb_str_new((char *)(data.data),data.length));
182
+ }
183
+
72
184
  static VALUE extract_value(UA_Variant value) { //{{{
73
185
  VALUE ret = rb_ary_new2(2);
74
186
  rb_ary_store(ret,0,Qnil);
75
187
  rb_ary_store(ret,1,Qnil);
76
- // printf("type: %s\n",value.type->typeName);
77
- if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_DATETIME])) {
78
- UA_DateTime raw = *(UA_DateTime *) value.data;
79
- rb_ary_store(ret,0,rb_time_new(UA_DateTime_toUnixTime(raw),0));
80
- rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.DateTime")));
81
- } else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_BOOLEAN])) {
82
- UA_Boolean raw = *(UA_Boolean *) value.data;
83
- rb_ary_store(ret,0,raw ? Qtrue : Qfalse);
84
- rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.Boolean")));
85
- } else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_DOUBLE])) {
86
- UA_Double raw = *(UA_Double *) value.data;
87
- rb_ary_store(ret,0,DBL2NUM(raw));
88
- rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.Double")));
89
- } else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_INT32])) {
90
- UA_Int32 raw = *(UA_Int32 *) value.data;
91
- rb_ary_store(ret,0,INT2NUM(raw));
92
- rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.Int32")));
93
- } else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_INT16])) {
94
- UA_Int16 raw = *(UA_Int16 *) value.data;
95
- rb_ary_store(ret,0,INT2NUM(raw));
96
- rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.Int16")));
97
- } else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_UINT32])) {
98
- UA_UInt32 raw = *(UA_UInt32 *) value.data;
99
- rb_ary_store(ret,0,UINT2NUM(raw));
100
- rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.UInt32")));
101
- } else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_UINT16])) {
102
- UA_UInt16 raw = *(UA_UInt16 *) value.data;
103
- rb_ary_store(ret,0,UINT2NUM(raw));
104
- rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.UInt16")));
105
- } else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_STRING])) {
106
- UA_String raw = *(UA_String *) value.data;
107
- rb_ary_store(ret,0,rb_str_export_locale(rb_str_new((char *)(raw.data),raw.length)));
108
- rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.String")));
188
+ //printf("type: %s\n",value.type->typeName);
189
+ //printf("dim: %ld\n",value.arrayDimensionsSize);
190
+ //printf("alen: %ld\n",value.arrayLength);
191
+ if (value.arrayDimensionsSize == 0 && value.arrayLength == 0) {
192
+ if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_DATETIME])) {
193
+ rb_ary_store(ret,0,UA_TYPES_DATETIME_to_value(*(UA_DateTime *)value.data));
194
+ rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.DateTime")));
195
+ } else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_BOOLEAN])) {
196
+ rb_ary_store(ret,0,UA_TYPES_BOOLEAN_to_value(*(UA_Boolean *)value.data));
197
+ rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.Boolean")));
198
+ } else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_DOUBLE])) {
199
+ rb_ary_store(ret,0,UA_TYPES_DOUBLE_to_value(*(UA_Double *)value.data));
200
+ rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.Double")));
201
+ } else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_INT32])) {
202
+ rb_ary_store(ret,0,UA_TYPES_INT32_to_value(*(UA_Int32 *)value.data));
203
+ rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.Int32")));
204
+ } else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_INT16])) {
205
+ rb_ary_store(ret,0,UA_TYPES_INT16_to_value(*(UA_Int16 *)value.data));
206
+ rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.Int16")));
207
+ } else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_UINT32])) {
208
+ rb_ary_store(ret,0,UA_TYPES_UINT32_to_value(*(UA_UInt32 *)value.data));
209
+ rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.UInt32")));
210
+ } else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_UINT16])) {
211
+ rb_ary_store(ret,0,UA_TYPES_UINT16_to_value(*(UA_UInt16 *)value.data));
212
+ rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.UInt16")));
213
+ } else if (UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_STRING])) {
214
+ rb_ary_store(ret,0,UA_TYPES_STRING_to_value(*(UA_String *)value.data));
215
+ rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.String")));
216
+ }
217
+ } else if (value.arrayDimensionsSize == 1 || (value.arrayDimensionsSize == 0 && value.arrayLength > 0)) {
218
+ if (UA_Variant_hasArrayType(&value, &UA_TYPES[UA_TYPES_DATETIME])) {
219
+ VALUE res = rb_ary_new();
220
+ rb_ary_store(ret,0,res);
221
+ rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.DateTime")));
222
+ for (int i=0; i < value.arrayLength; i++) {
223
+ rb_ary_push(res,UA_TYPES_DATETIME_to_value(((UA_DateTime *)value.data)[i]));
224
+ }
225
+ } else if (UA_Variant_hasArrayType(&value, &UA_TYPES[UA_TYPES_BOOLEAN])) {
226
+ VALUE res = rb_ary_new();
227
+ rb_ary_store(ret,0,res);
228
+ rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.Boolean")));
229
+ for (int i=0; i < value.arrayLength; i++) {
230
+ rb_ary_push(res,UA_TYPES_BOOLEAN_to_value(((UA_Boolean *)value.data)[i]));
231
+ }
232
+ } else if (UA_Variant_hasArrayType(&value, &UA_TYPES[UA_TYPES_DOUBLE])) {
233
+ VALUE res = rb_ary_new();
234
+ rb_ary_store(ret,0,res);
235
+ rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.Double")));
236
+ for (int i=0; i < value.arrayLength; i++) {
237
+ rb_ary_push(res,UA_TYPES_DOUBLE_to_value(((UA_Double *)value.data)[i]));
238
+ }
239
+ } else if (UA_Variant_hasArrayType(&value, &UA_TYPES[UA_TYPES_INT32])) {
240
+ VALUE res = rb_ary_new();
241
+ rb_ary_store(ret,0,res);
242
+ rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.Int32")));
243
+ for (int i=0; i < value.arrayLength; i++) {
244
+ rb_ary_push(res,UA_TYPES_INT32_to_value(((UA_Int32 *)value.data)[i]));
245
+ }
246
+ } else if (UA_Variant_hasArrayType(&value, &UA_TYPES[UA_TYPES_INT16])) {
247
+ VALUE res = rb_ary_new();
248
+ rb_ary_store(ret,0,res);
249
+ rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.Int16")));
250
+ for (int i=0; i < value.arrayLength; i++) {
251
+ rb_ary_push(res,UA_TYPES_INT16_to_value(((UA_Int16 *)value.data)[i]));
252
+ }
253
+ } else if (UA_Variant_hasArrayType(&value, &UA_TYPES[UA_TYPES_UINT32])) {
254
+ VALUE res = rb_ary_new();
255
+ rb_ary_store(ret,0,res);
256
+ rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.UInt32")));
257
+ for (int i=0; i < value.arrayLength; i++) {
258
+ rb_ary_push(res,UA_TYPES_UINT32_to_value(((UA_UInt32 *)value.data)[i]));
259
+ }
260
+ } else if (UA_Variant_hasArrayType(&value, &UA_TYPES[UA_TYPES_UINT16])) {
261
+ VALUE res = rb_ary_new();
262
+ rb_ary_store(ret,0,res);
263
+ rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.UInt16")));
264
+ for (int i=0; i < value.arrayLength; i++) {
265
+ rb_ary_push(res,UA_TYPES_UINT16_to_value(((UA_UInt16 *)value.data)[i]));
266
+ }
267
+ } else if (UA_Variant_hasArrayType(&value, &UA_TYPES[UA_TYPES_STRING])) {
268
+ VALUE res = rb_ary_new();
269
+ rb_ary_store(ret,0,res);
270
+ rb_ary_store(ret,1,ID2SYM(rb_intern("VariantType.String")));
271
+ for (int i=0; i < value.arrayLength; i++) {
272
+ rb_ary_push(res,UA_TYPES_STRING_to_value(((UA_String *)value.data)[i]));
273
+ }
274
+ }
109
275
  }
110
-
111
276
  return ret;
112
277
  } //}}}
113
278
  /* ++ */
@@ -8,6 +8,17 @@ require 'daemonite'
8
8
  module OPCUA
9
9
  class Client
10
10
  alias_method :initialize_base, :initialize
11
+ alias_method :get_base, :get
12
+
13
+ def get(*a)
14
+ if a.length == 1 && a[0].to_s =~ /ns=(\d+);i=(.*)/
15
+ get_base $1.to_i, $2.to_i
16
+ elsif a.length == 1 && a[0].to_s =~ /ns=(\d+);s=(.*)/
17
+ get_base $1.to_i, $2
18
+ else
19
+ get_base *a
20
+ end
21
+ end
11
22
 
12
23
  def initialize(url)
13
24
  if url =~ /(^[^:]+):\/\/([^:]+):([^@]+)@(.*)$/
@@ -4,3 +4,54 @@ else
4
4
  require_relative 'server.so'
5
5
  end
6
6
  require 'daemonite'
7
+
8
+ module OPCUA
9
+ class Server
10
+ alias_method :get_base, :get
11
+
12
+ def get(*a)
13
+ if a.length == 1 && a[0].to_s =~ /ns=(\d+);i=(.*)/
14
+ get_base $1.to_i, $2.to_i
15
+ elsif a.length == 1 && a[0].to_s =~ /ns=(\d+);s=(.*)/
16
+ get_base $1.to_i, $2
17
+ else
18
+ get_base *a
19
+ end
20
+ end
21
+
22
+ class ObjectNode
23
+ alias_method :find_one, :find
24
+
25
+ def find(*what)
26
+ if what.length == 0
27
+ nil
28
+ elsif what.length == 1
29
+ find_one what[0]
30
+ else
31
+ what.map{|e| find_one e}
32
+ end
33
+ end
34
+ end
35
+
36
+ class TypeSubNode
37
+ def add_property(name)
38
+ add_variable name, OPCUA::PROPERTYTYPE
39
+ end
40
+ def add_property_rw
41
+ add_variable_rw name, OPCUA::PROPERTYTYPE
42
+ end
43
+ def add_properties(*item)
44
+ item.each { |e| add_property e }
45
+ end
46
+ def add_property_rw(*item)
47
+ item.each { |e| add_property_rw e }
48
+ end
49
+ def add_variables(*item)
50
+ item.each { |e| add_variable e }
51
+ end
52
+ def add_variables_rw(*item)
53
+ item.each { |e| add_variable_rw e }
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "opcua"
3
- s.version = "0.11"
3
+ s.version = "0.12"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.license = "LGPL-3.0"
6
6
  s.summary = "Preliminary release of opcua (open62541) ruby bindings. C performance, Ruby elegance, simplicity, and productivity."
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opcua
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.11'
4
+ version: '0.12'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juergen eTM Mangler
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: tools
11
11
  cert_chain: []
12
- date: 2019-06-03 00:00:00.000000000 Z
12
+ date: 2019-06-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: daemonite
@@ -73,7 +73,10 @@ files:
73
73
  - Rakefile
74
74
  - cert/cert.h
75
75
  - cert/cert_key.h
76
+ - example/client_get_sync.rb
77
+ - example/client_get_value.rb
76
78
  - example/client_method.rb
79
+ - example/client_set_value.rb
77
80
  - example/client_subscription.rb
78
81
  - example/kelch.KMT
79
82
  - example/server.rb