opcua 0.11 → 0.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -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