opcua_client 0.0.1 → 0.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ece180c3aa8255995c232d04ab6edd8d698534a2e7a07f95feb67aee06dce5c
4
- data.tar.gz: 1478ab14003bdc8c6da023fc53eef15b5d8e0e5f76850c1773b087563e0ae80d
3
+ metadata.gz: 6d5c48f943609a5cff626ade2e52495427fc8c3b3af175c2ac9b7231146209ec
4
+ data.tar.gz: f0ec2ea830a866681352b2048950382a06d199ea1f53b47a31857b1f066a3c2f
5
5
  SHA512:
6
- metadata.gz: 39fcbe3246e1f1c416e3d4258e395d0d12da62dfd4c7c64b5151a6bc8b308c243baa880519161b8fb13e891bdcacad6f5da3e3fa9875973526ae1cfa300376c0
7
- data.tar.gz: 3f0057136a51a9a7c08df5be42df6b95291810dea18cfc7e2369712e05fdf40ffba3d2ead4d159f94994d6995abcf6e96e81f1b3a5c6cfe9933b30e6641d1500
6
+ metadata.gz: 54bacd20dd2f8f73c10dacd29f1b9ab3776ee1cec0933aa1c56423a9cc077161c5d1c0fb676111b679f80eae434640cbeb5cce2d12d254fd5877927d18142acc
7
+ data.tar.gz: 270a0757c4d3469e7e3e6cbf57e874d4ec13911d221bc3befb4a257abf237b0b7307bed5f14960b5381d3ddcf74e4c77d014e778d09efb389c75a957056bb9f3
data/README.md CHANGED
@@ -35,6 +35,9 @@ begin
35
35
  # write to ns=2;s=1
36
36
  client.write_int16(2, "1", 888)
37
37
  puts client.read_int16(2, "1")
38
+
39
+ client.multi_write_int16(2, (1..10).map{|x| "action_#{x}"}, (1..10).map{|x| x * 10}) # 10x writes
40
+ client.multi_write_int32(2, (1..10).map{|x| "amount_#{x}"}, (1..10).map{|x| x * 10 + 1}) # 10x writes
38
41
  ensure
39
42
  client.disconnect
40
43
  end
@@ -57,6 +60,10 @@ All methods raise OPCUAClient::Error if unsuccessful.
57
60
  * ```client.write_int32(Fixnum ns, String name, Fixnum value)```
58
61
  * ```client.write_float(Fixnum ns, String name, Float value)```
59
62
  * ```client.write_boolean(Fixnum ns, String name, bool value)```
63
+ * ```client.multi_write_int16(Fixnum ns, Array[String] names, Array[Fixnum] values)```
64
+ * ```client.multi_write_int32(Fixnum ns, Array[String] names, Array[Fixnum] values)```
65
+ * ```client.multi_write_float(Fixnum ns, Array[String] names, Array[Float] values)```
66
+ * ```client.multi_write_boolean(Fixnum ns, Array[String] names, Array[bool] values)```
60
67
 
61
68
  ### Available methods - misc:
62
69
 
@@ -247,6 +247,152 @@ static VALUE rb_disconnect(VALUE self) {
247
247
  return RB_UINT2NUM(status);
248
248
  }
249
249
 
250
+ static UA_StatusCode multiWrite(UA_Client *client, const UA_NodeId *nodeId, const UA_Variant *in, const long varsSize) {
251
+ UA_AttributeId attributeId = UA_ATTRIBUTEID_VALUE;
252
+
253
+ UA_UInt16 wvSize = UA_TYPES[UA_TYPES_WRITEVALUE].memSize;
254
+
255
+ UA_WriteValue *wValues = UA_calloc(varsSize, wvSize);
256
+
257
+ for (int i=0; i<varsSize; i++) {
258
+ UA_WriteValue *wValue = &wValues[i];
259
+ wValue->attributeId = attributeId;
260
+ wValue->nodeId = nodeId[i];
261
+ wValue->value.value = in[i];
262
+ wValue->value.hasValue = true;
263
+ }
264
+
265
+ UA_WriteRequest wReq;
266
+ UA_WriteRequest_init(&wReq);
267
+ wReq.nodesToWrite = wValues;
268
+ wReq.nodesToWriteSize = varsSize;
269
+
270
+ UA_WriteResponse wResp = UA_Client_Service_write(client, wReq);
271
+
272
+ UA_StatusCode retval = wResp.responseHeader.serviceResult;
273
+ if(retval == UA_STATUSCODE_GOOD) {
274
+ if(wResp.resultsSize == varsSize) {
275
+ retval = wResp.results[0];
276
+
277
+ for (int i=0; i<wResp.resultsSize; i++) {
278
+ if (wResp.results[i] != UA_STATUSCODE_GOOD) {
279
+ retval = wResp.results[i];
280
+ // printf("%s\n", "multiWrite: bad result found");
281
+ break;
282
+ }
283
+ }
284
+
285
+ if (retval == UA_STATUSCODE_GOOD) {
286
+ // printf("%s\n", "multiWrite: all vars written");
287
+ }
288
+ } else {
289
+ retval = UA_STATUSCODE_BADUNEXPECTEDERROR;
290
+ // printf("%s\n", "multiWrite: bad resultsSize");
291
+ }
292
+ } else {
293
+ // printf("%s\n", "multiWrite: bad write");
294
+ }
295
+
296
+ UA_WriteResponse_deleteMembers(&wResp);
297
+ UA_free(wValues);
298
+
299
+ return retval;
300
+ }
301
+
302
+ static VALUE rb_writeUaValues(VALUE self, VALUE v_nsIndex, VALUE v_aryNames, VALUE v_aryNewValues, int uaType) {
303
+ if (RB_TYPE_P(v_nsIndex, T_FIXNUM) != 1) {
304
+ return raise_invalid_arguments_error();
305
+ }
306
+
307
+ Check_Type(v_aryNames, T_ARRAY);
308
+ Check_Type(v_aryNewValues, T_ARRAY);
309
+
310
+ const long namesCount = RARRAY_LEN(v_aryNames);
311
+ const long valuesCount = RARRAY_LEN(v_aryNewValues);
312
+
313
+ if (namesCount != valuesCount) {
314
+ return raise_invalid_arguments_error();
315
+ }
316
+
317
+ int nsIndex = FIX2INT(v_nsIndex);
318
+
319
+ struct UninitializedClient * uclient;
320
+ TypedData_Get_Struct(self, struct UninitializedClient, &UA_Client_Type, uclient);
321
+ UA_Client *client = uclient->client;
322
+
323
+ UA_UInt16 nidSize = UA_TYPES[UA_TYPES_NODEID].memSize;
324
+ UA_UInt16 variantSize = UA_TYPES[UA_TYPES_VARIANT].memSize;
325
+
326
+ UA_NodeId *nodes = UA_calloc(namesCount, nidSize);
327
+ UA_Variant *values = UA_calloc(namesCount, variantSize);
328
+
329
+ for (int i=0; i<namesCount; i++) {
330
+ VALUE v_name = rb_ary_entry(v_aryNames, i);
331
+ VALUE v_newValue = rb_ary_entry(v_aryNewValues, i);
332
+
333
+ if (RB_TYPE_P(v_name, T_STRING) != 1) {
334
+ return raise_invalid_arguments_error();
335
+ }
336
+
337
+ char *name = StringValueCStr(v_name);
338
+ nodes[i] = UA_NODEID_STRING(nsIndex, name);
339
+
340
+ if (uaType == UA_TYPES_INT16) {
341
+ Check_Type(v_newValue, T_FIXNUM);
342
+ UA_Int16 newValue = NUM2SHORT(v_newValue);
343
+ values[i].data = UA_malloc(sizeof(UA_Int16));
344
+ *(UA_Int16*)values[i].data = newValue;
345
+ values[i].type = &UA_TYPES[UA_TYPES_INT16];
346
+ } else if (uaType == UA_TYPES_INT32) {
347
+ Check_Type(v_newValue, T_FIXNUM);
348
+ UA_Int32 newValue = NUM2INT(v_newValue);
349
+ values[i].data = UA_malloc(sizeof(UA_Int32));
350
+ *(UA_Int32*)values[i].data = newValue;
351
+ values[i].type = &UA_TYPES[UA_TYPES_INT32];
352
+ } else if (uaType == UA_TYPES_FLOAT) {
353
+ Check_Type(v_newValue, T_FLOAT);
354
+ UA_Float newValue = NUM2DBL(v_newValue);
355
+ values[i].data = UA_malloc(sizeof(UA_Float));
356
+ *(UA_Float*)values[i].data = newValue;
357
+ values[i].type = &UA_TYPES[UA_TYPES_FLOAT];
358
+ } else if (uaType == UA_TYPES_BOOLEAN) {
359
+ if (RB_TYPE_P(v_newValue, T_TRUE) != 1 && RB_TYPE_P(v_newValue, T_FALSE) != 1) {
360
+ return raise_invalid_arguments_error();
361
+ }
362
+ UA_Boolean newValue = RTEST(v_newValue);
363
+ values[i].data = UA_malloc(sizeof(UA_Boolean));
364
+ *(UA_Boolean*)values[i].data = newValue;
365
+ values[i].type = &UA_TYPES[UA_TYPES_BOOLEAN];
366
+ } else {
367
+ rb_raise(cError, "Unsupported type");
368
+ }
369
+ }
370
+
371
+ UA_StatusCode status = multiWrite(client, nodes, values, namesCount);
372
+
373
+ if (status == UA_STATUSCODE_GOOD) {
374
+ // printf("%s\n", "value write successful");
375
+ } else {
376
+ /* Clean up */
377
+ for (int i=0; i<namesCount; i++) {
378
+ UA_Variant_deleteMembers(&values[i]);
379
+ }
380
+ UA_free(nodes);
381
+ UA_free(values);
382
+
383
+ return raise_ua_status_error(status);
384
+ }
385
+
386
+ /* Clean up */
387
+ for (int i=0; i<namesCount; i++) {
388
+ UA_Variant_deleteMembers(&values[i]);
389
+ }
390
+ UA_free(nodes);
391
+ UA_free(values);
392
+
393
+ return Qnil;
394
+ }
395
+
250
396
  static VALUE rb_writeUaValue(VALUE self, VALUE v_nsIndex, VALUE v_name, VALUE v_newValue, int uaType) {
251
397
  if (RB_TYPE_P(v_name, T_STRING) != 1) {
252
398
  return raise_invalid_arguments_error();
@@ -314,18 +460,34 @@ static VALUE rb_writeInt16Value(VALUE self, VALUE v_nsIndex, VALUE v_name, VALUE
314
460
  return rb_writeUaValue(self, v_nsIndex, v_name, v_newValue, UA_TYPES_INT16);
315
461
  }
316
462
 
463
+ static VALUE rb_writeInt16Values(VALUE self, VALUE v_nsIndex, VALUE v_aryNames, VALUE v_aryNewValues) {
464
+ return rb_writeUaValues(self, v_nsIndex, v_aryNames, v_aryNewValues, UA_TYPES_INT16);
465
+ }
466
+
317
467
  static VALUE rb_writeInt32Value(VALUE self, VALUE v_nsIndex, VALUE v_name, VALUE v_newValue) {
318
468
  return rb_writeUaValue(self, v_nsIndex, v_name, v_newValue, UA_TYPES_INT32);
319
469
  }
320
470
 
471
+ static VALUE rb_writeInt32Values(VALUE self, VALUE v_nsIndex, VALUE v_aryNames, VALUE v_aryNewValues) {
472
+ return rb_writeUaValues(self, v_nsIndex, v_aryNames, v_aryNewValues, UA_TYPES_INT32);
473
+ }
474
+
321
475
  static VALUE rb_writeBooleanValue(VALUE self, VALUE v_nsIndex, VALUE v_name, VALUE v_newValue) {
322
476
  return rb_writeUaValue(self, v_nsIndex, v_name, v_newValue, UA_TYPES_BOOLEAN);
323
477
  }
324
478
 
479
+ static VALUE rb_writeBooleanValues(VALUE self, VALUE v_nsIndex, VALUE v_aryNames, VALUE v_aryNewValues) {
480
+ return rb_writeUaValues(self, v_nsIndex, v_aryNames, v_aryNewValues, UA_TYPES_BOOLEAN);
481
+ }
482
+
325
483
  static VALUE rb_writeFloatValue(VALUE self, VALUE v_nsIndex, VALUE v_name, VALUE v_newValue) {
326
484
  return rb_writeUaValue(self, v_nsIndex, v_name, v_newValue, UA_TYPES_FLOAT);
327
485
  }
328
486
 
487
+ static VALUE rb_writeFloatValues(VALUE self, VALUE v_nsIndex, VALUE v_aryNames, VALUE v_aryNewValues) {
488
+ return rb_writeUaValues(self, v_nsIndex, v_aryNames, v_aryNewValues, UA_TYPES_FLOAT);
489
+ }
490
+
329
491
  static VALUE rb_readUaValue(VALUE self, VALUE v_nsIndex, VALUE v_name, int type) {
330
492
  if (RB_TYPE_P(v_name, T_STRING) != 1) {
331
493
  return raise_invalid_arguments_error();
@@ -486,6 +648,12 @@ void Init_opcua_client()
486
648
  rb_define_method(cClient, "write_boolean", rb_writeBooleanValue, 3);
487
649
  rb_define_method(cClient, "write_bool", rb_writeBooleanValue, 3);
488
650
 
651
+ rb_define_method(cClient, "multi_write_int16", rb_writeInt16Values, 3);
652
+ rb_define_method(cClient, "multi_write_int32", rb_writeInt32Values, 3);
653
+ rb_define_method(cClient, "multi_write_float", rb_writeFloatValues, 3);
654
+ rb_define_method(cClient, "multi_write_boolean", rb_writeBooleanValues, 3);
655
+ rb_define_method(cClient, "multi_write_bool", rb_writeBooleanValues, 3);
656
+
489
657
  rb_define_method(cClient, "create_subscription", rb_createSubscription, 0);
490
658
  rb_define_method(cClient, "add_monitored_item", rb_addMonitoredItem, 3);
491
659
 
@@ -1,3 +1,3 @@
1
1
  module OPCUAClient
2
- VERSION = "0.0.1".freeze
2
+ VERSION = "0.0.2".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opcua_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ritvars Rundzans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-04 00:00:00.000000000 Z
11
+ date: 2020-02-04 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: