opcua_client 0.0.3 → 0.0.4

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: 7fd39e3b07294cf1cf3f7e037c6bb31e202f8d4279e7ff59c06ec1f709641654
4
- data.tar.gz: a2385d369880786ae3e970625c2a9419ab6c97bf63f861e496b90161aa280cf1
3
+ metadata.gz: 93f9f3a4464f5273ae87fb6e0d3c75ec902db88a659e48d40dd6da7bd75b0168
4
+ data.tar.gz: bff1a7a86aca728eb200099d62d594b79cc7ae4800c4337ab0b8370e50c6d435
5
5
  SHA512:
6
- metadata.gz: 5652899ac7728aa8b2efc6ed0fcd9b9021f9d864cb68f98aafe7665026215b740afda38557e05f1c714dd77199ff8c38f984ad0605adc21371e9f3d727408b5f
7
- data.tar.gz: e6a3bef6175e9ebef8b4422e2f97f48a856d873349520470f700cb05200419a22ca95e98e1d0c6aa2cfa73465ddd96e149c5c86cdbe004fa453cc37654d0c9c5
6
+ metadata.gz: 83ed7b449e8e3203750d48a8e1352035931f35515d91d85c2be52ebc38b5293a04444c449d25ec850026c8edfd3184ef1f83cd2a8ab632b8718f85f5ba62815f
7
+ data.tar.gz: 2fa13a2d7d99b6534a6db547b8a0419a1bd1b5488b881d80d1b2d3d9537628c5c97257aa56420cc0d739cbe47d16e74b0bd52d01f05d91562f4e735357439267
@@ -247,6 +247,66 @@ static VALUE rb_disconnect(VALUE self) {
247
247
  return RB_UINT2NUM(status);
248
248
  }
249
249
 
250
+ static UA_StatusCode multiRead(UA_Client *client, const UA_NodeId *nodeId, UA_Variant *out, const long varsCount) {
251
+
252
+ UA_UInt16 rvSize = UA_TYPES[UA_TYPES_READVALUEID].memSize;
253
+ UA_ReadValueId *rValues = UA_calloc(varsCount, rvSize);
254
+
255
+ for (int i=0; i<varsCount; i++) {
256
+ UA_ReadValueId *readItem = &rValues[i];
257
+ readItem->nodeId = nodeId[i];
258
+ readItem->attributeId = UA_ATTRIBUTEID_VALUE;
259
+ }
260
+
261
+ UA_ReadRequest request;
262
+ UA_ReadRequest_init(&request);
263
+ request.nodesToRead = rValues;
264
+ request.nodesToReadSize = varsCount;
265
+
266
+ UA_ReadResponse response = UA_Client_Service_read(client, request);
267
+ UA_StatusCode retval = response.responseHeader.serviceResult;
268
+ if(retval == UA_STATUSCODE_GOOD) {
269
+ if(response.resultsSize == varsCount)
270
+ retval = response.results[0].status;
271
+ else
272
+ retval = UA_STATUSCODE_BADUNEXPECTEDERROR;
273
+ }
274
+
275
+ if(retval != UA_STATUSCODE_GOOD) {
276
+ UA_ReadResponse_deleteMembers(&response);
277
+ UA_free(rValues);
278
+ return retval;
279
+ }
280
+
281
+ /* Set the StatusCode */
282
+ UA_DataValue *results = response.results;
283
+
284
+ if (response.resultsSize != varsCount) {
285
+ retval = UA_STATUSCODE_BADUNEXPECTEDERROR;
286
+ UA_ReadResponse_deleteMembers(&response);
287
+ UA_free(rValues);
288
+ return retval;
289
+ }
290
+
291
+ for (int i=0; i<varsCount; i++) {
292
+ if ((results[i].hasStatus && results[i].status != UA_STATUSCODE_GOOD) || !results[i].hasValue) {
293
+ retval = UA_STATUSCODE_BADUNEXPECTEDERROR;
294
+ UA_ReadResponse_deleteMembers(&response);
295
+ UA_free(rValues);
296
+ return retval;
297
+ }
298
+ }
299
+
300
+ for (int i=0; i<varsCount; i++) {
301
+ out[i] = results[i].value;
302
+ UA_Variant_init(&results[i].value);
303
+ }
304
+
305
+ UA_ReadResponse_deleteMembers(&response);
306
+ UA_free(rValues);
307
+ return retval;
308
+ }
309
+
250
310
  static UA_StatusCode multiWrite(UA_Client *client, const UA_NodeId *nodeId, const UA_Variant *in, const long varsSize) {
251
311
  UA_AttributeId attributeId = UA_ATTRIBUTEID_VALUE;
252
312
 
@@ -299,6 +359,96 @@ static UA_StatusCode multiWrite(UA_Client *client, const UA_NodeId *nodeId, cons
299
359
  return retval;
300
360
  }
301
361
 
362
+ static VALUE rb_readUaValues(VALUE self, VALUE v_nsIndex, VALUE v_aryNames) {
363
+ if (RB_TYPE_P(v_nsIndex, T_FIXNUM) != 1) {
364
+ return raise_invalid_arguments_error();
365
+ }
366
+
367
+ Check_Type(v_aryNames, T_ARRAY);
368
+ const long namesCount = RARRAY_LEN(v_aryNames);
369
+
370
+ int nsIndex = FIX2INT(v_nsIndex);
371
+
372
+ struct UninitializedClient * uclient;
373
+ TypedData_Get_Struct(self, struct UninitializedClient, &UA_Client_Type, uclient);
374
+ UA_Client *client = uclient->client;
375
+
376
+ UA_UInt16 nidSize = UA_TYPES[UA_TYPES_NODEID].memSize;
377
+ UA_UInt16 variantSize = UA_TYPES[UA_TYPES_VARIANT].memSize;
378
+
379
+ UA_NodeId *nodes = UA_calloc(namesCount, nidSize);
380
+ UA_Variant *readValues = UA_calloc(namesCount, variantSize);
381
+
382
+ for (int i=0; i<namesCount; i++) {
383
+ VALUE v_name = rb_ary_entry(v_aryNames, i);
384
+
385
+ if (RB_TYPE_P(v_name, T_STRING) != 1) {
386
+ return raise_invalid_arguments_error();
387
+ }
388
+
389
+ char *name = StringValueCStr(v_name);
390
+ nodes[i] = UA_NODEID_STRING(nsIndex, name);
391
+ }
392
+
393
+ UA_StatusCode status = multiRead(client, nodes, readValues, namesCount);
394
+
395
+ VALUE resultArray = Qnil;
396
+
397
+ if (status == UA_STATUSCODE_GOOD) {
398
+ // printf("%s\n", "value read successful");
399
+
400
+ resultArray = rb_ary_new2(namesCount);
401
+
402
+ for (int i=0; i<namesCount; i++) {
403
+ // printf("the value is: %i\n", val);
404
+
405
+ VALUE rubyVal = Qnil;
406
+
407
+ if (UA_Variant_hasScalarType(&readValues[i], &UA_TYPES[UA_TYPES_INT16])) {
408
+ UA_Int16 val = *(UA_Int16*)readValues[i].data;
409
+ rubyVal = INT2FIX(val);
410
+ } else if (UA_Variant_hasScalarType(&readValues[i], &UA_TYPES[UA_TYPES_UINT16])) {
411
+ UA_UInt16 val = *(UA_UInt16*)readValues[i].data;
412
+ rubyVal = INT2FIX(val);
413
+ } else if (UA_Variant_hasScalarType(&readValues[i], &UA_TYPES[UA_TYPES_INT32])) {
414
+ UA_Int32 val = *(UA_Int32*)readValues[i].data;
415
+ rubyVal = INT2FIX(val);
416
+ } else if (UA_Variant_hasScalarType(&readValues[i], &UA_TYPES[UA_TYPES_UINT32])) {
417
+ UA_UInt32 val = *(UA_UInt32*)readValues[i].data;
418
+ rubyVal = INT2FIX(val);
419
+ } else if (UA_Variant_hasScalarType(&readValues[i], &UA_TYPES[UA_TYPES_BOOLEAN])) {
420
+ UA_Boolean val = *(UA_Boolean*)readValues[i].data;
421
+ rubyVal = val ? Qtrue : Qfalse;
422
+ } else if (UA_Variant_hasScalarType(&readValues[i], &UA_TYPES[UA_TYPES_FLOAT])) {
423
+ UA_Float val = *(UA_Float*)readValues[i].data;
424
+ rubyVal = DBL2NUM(val);
425
+ } else {
426
+ rubyVal = Qnil; // unsupported
427
+ }
428
+
429
+ rb_ary_push(resultArray, rubyVal);
430
+ }
431
+ } else {
432
+ /* Clean up */
433
+ for (int i=0; i<namesCount; i++) {
434
+ UA_Variant_deleteMembers(&readValues[i]);
435
+ }
436
+ UA_free(nodes);
437
+ UA_free(readValues);
438
+
439
+ return raise_ua_status_error(status);
440
+ }
441
+
442
+ /* Clean up */
443
+ for (int i=0; i<namesCount; i++) {
444
+ UA_Variant_deleteMembers(&readValues[i]);
445
+ }
446
+ UA_free(nodes);
447
+ UA_free(readValues);
448
+
449
+ return resultArray;
450
+ }
451
+
302
452
  static VALUE rb_writeUaValues(VALUE self, VALUE v_nsIndex, VALUE v_aryNames, VALUE v_aryNewValues, int uaType) {
303
453
  if (RB_TYPE_P(v_nsIndex, T_FIXNUM) != 1) {
304
454
  return raise_invalid_arguments_error();
@@ -695,6 +845,8 @@ void Init_opcua_client()
695
845
  rb_define_method(cClient, "multi_write_boolean", rb_writeBooleanValues, 3);
696
846
  rb_define_method(cClient, "multi_write_bool", rb_writeBooleanValues, 3);
697
847
 
848
+ rb_define_method(cClient, "multi_read", rb_readUaValues, 2);
849
+
698
850
  rb_define_method(cClient, "create_subscription", rb_createSubscription, 0);
699
851
  rb_define_method(cClient, "add_monitored_item", rb_addMonitoredItem, 3);
700
852
 
@@ -1,3 +1,3 @@
1
1
  module OPCUAClient
2
- VERSION = "0.0.3".freeze
2
+ VERSION = "0.0.4".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.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ritvars Rundzans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-18 00:00:00.000000000 Z
11
+ date: 2020-03-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: