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 +4 -4
- data/README.md +7 -0
- data/ext/opcua_client/opcua_client.c +168 -0
- data/lib/opcua_client/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d5c48f943609a5cff626ade2e52495427fc8c3b3af175c2ac9b7231146209ec
|
4
|
+
data.tar.gz: f0ec2ea830a866681352b2048950382a06d199ea1f53b47a31857b1f066a3c2f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
|
data/lib/opcua_client/version.rb
CHANGED
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.
|
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:
|
11
|
+
date: 2020-02-04 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|