ads-client 2.0.0-beta.3 → 2.0.0-beta.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.
@@ -659,7 +659,7 @@ class Client extends events_1.default {
659
659
  };
660
660
  this.socket?.once('error', errorHandler);
661
661
  try {
662
- await this.socketWrite(packet);
662
+ this.socketWrite(packet);
663
663
  }
664
664
  catch (err) {
665
665
  this.socket?.off('error', errorHandler);
@@ -715,15 +715,45 @@ class Client extends events_1.default {
715
715
  //Sometimes close event is not received, so resolve already here
716
716
  this.socket.once('end', () => {
717
717
  this.debugD(`unregisterAdsPort(): Socket connection ended, connection closed.`);
718
+ clearTimeout(this.portRegisterTimeoutTimer);
719
+ this.amsTcpCallback = undefined;
718
720
  this.socket?.destroy();
719
721
  resolve();
720
722
  });
723
+ this.amsTcpCallback = (res) => {
724
+ this.amsTcpCallback = undefined;
725
+ clearTimeout(this.portRegisterTimeoutTimer);
726
+ if (res.amsTcp.command === ADS.AMS_HEADER_FLAG.AMS_TCP_PORT_CLOSE) {
727
+ this.debug(`unregisterAdsPort(): ADS port unregistered`);
728
+ this.socket?.destroy();
729
+ resolve();
730
+ }
731
+ };
732
+ //Timeout (if no answer from router)
733
+ this.portRegisterTimeoutTimer = setTimeout(() => {
734
+ //Callback is no longer needed, delete it
735
+ this.amsTcpCallback = undefined;
736
+ //Create a custom "ads error" so that the info is passed onwards
737
+ const adsError = {
738
+ ads: {
739
+ error: true,
740
+ errorCode: -1,
741
+ errorStr: `Timeout - no response in ${this.settings.timeoutDelay} ms`
742
+ }
743
+ };
744
+ this.debug(`unregisterAdsPort(): Failed to unregister ADS port: Timeout - no response in ${this.settings.timeoutDelay} ms`);
745
+ return reject(new client_error_1.default(`unregisterAdsPort(): Timeout - no response in ${this.settings.timeoutDelay} ms`, adsError));
746
+ }, this.settings.timeoutDelay);
721
747
  try {
722
- await this.socketWrite(buffer);
748
+ this.socketWrite(buffer);
723
749
  }
724
750
  catch (err) {
725
751
  reject(err);
726
752
  }
753
+ finally {
754
+ this.amsTcpCallback = undefined;
755
+ clearTimeout(this.portRegisterTimeoutTimer);
756
+ }
727
757
  });
728
758
  }
729
759
  /**
@@ -1379,7 +1409,12 @@ class Client extends events_1.default {
1379
1409
  //AMS port unregister
1380
1410
  case ADS.AMS_HEADER_FLAG.AMS_TCP_PORT_CLOSE:
1381
1411
  packet.amsTcp.commandStr = 'Port unregister';
1382
- //No action at the moment
1412
+ if (this.amsTcpCallback) {
1413
+ this.amsTcpCallback(packet);
1414
+ }
1415
+ else {
1416
+ this.debug(`onAmsTcpPacketReceived(): Port unregister response received but no callback was assigned (${packet.amsTcp.commandStr})`);
1417
+ }
1383
1418
  break;
1384
1419
  //AMS port register
1385
1420
  case ADS.AMS_HEADER_FLAG.AMS_TCP_PORT_CONNECT:
@@ -2325,6 +2360,7 @@ class Client extends events_1.default {
2325
2360
  if (err.adsError && err.adsError?.errorCode === 1808) {
2326
2361
  //Type wasn't found.
2327
2362
  //Might be TwinCAT 2 system that doesn't provide pseudo or base data types by ADS --> check if we know the type ourselves
2363
+ const originalName = name;
2328
2364
  if (ADS.BASE_DATA_TYPES.isPseudoType(name)) {
2329
2365
  //This converts e.g. PVOID to a primitive type
2330
2366
  if (knownSize === undefined) {
@@ -2358,6 +2394,11 @@ class Client extends events_1.default {
2358
2394
  extendedFlags: 0,
2359
2395
  reserved: Buffer.alloc(0)
2360
2396
  };
2397
+ //Adding to cache, even though it's not read from the target
2398
+ //With TwinCAT 2, this prevents trying to read base types again and again from the target (as there aren't any)
2399
+ if (!this.settings.disableCaching && !targetOpts.adsPort && !targetOpts.amsNetId) {
2400
+ this.metaData.plcDataTypes[originalName.toLowerCase()] = dataType;
2401
+ }
2361
2402
  }
2362
2403
  else {
2363
2404
  //Type is unknown - we can't do anything
@@ -2401,7 +2442,7 @@ class Client extends events_1.default {
2401
2442
  }
2402
2443
  }
2403
2444
  else if ((((dataType.type === '' && !ADS.BASE_DATA_TYPES.isPseudoType(dataType.name)) || ADS.BASE_DATA_TYPES.isKnownType(dataType.name))
2404
- && dataType.flagsStr.includes('DataType')
2445
+ && (dataType.flagsStr.includes('DataType') || ADS.BASE_DATA_TYPES.isKnownType(dataType.name)) //isKnownType() call is for TwinCAT 2 support, as base types (like INT16) do not have DataType flag (but it's the final base type)
2405
2446
  && !dataType.flagsStr.includes('EnumInfos')
2406
2447
  && dataType.arrayDimension === 0)) {
2407
2448
  //This is final form (no need to go deeper)
@@ -2409,8 +2450,10 @@ class Client extends events_1.default {
2409
2450
  }
2410
2451
  else if (dataType.arrayDimension > 0) {
2411
2452
  //Data type is an array - get array subtype
2453
+ //TwinCAT 2 support - calculate size if it's array of pointer etc.
2454
+ const size = dataType.size / dataType.arrayInfos.reduce((total, dimension) => total * dimension.length, 1);
2412
2455
  builtType = {
2413
- ...(await this.buildDataType(dataType.type, targetOpts, false))
2456
+ ...(await this.buildDataType(dataType.type, targetOpts, false, size))
2414
2457
  };
2415
2458
  builtType.arrayInfos = [...dataType.arrayInfos, ...builtType.arrayInfos];
2416
2459
  }
@@ -3381,7 +3424,7 @@ class Client extends events_1.default {
3381
3424
  * @example
3382
3425
  * ```js
3383
3426
  * try {
3384
- * const symbol = await client.getSymbol('GVL_Test.ExampleStruct');
3427
+ * const symbol = await client.getSymbol('GVL_Read.StandardTypes.INT_');
3385
3428
  * } catch (err) {
3386
3429
  * console.log("Error:", err);
3387
3430
  * }
@@ -3677,7 +3720,7 @@ class Client extends events_1.default {
3677
3720
  * //Checks if value has changed every 100ms
3678
3721
  * //Callback is called only when the value has changed
3679
3722
  * await client.subscribeValue(
3680
- * 'GVL_Test.ExampleStruct.',
3723
+ * 'GVL_Subscription.NumericValue_10ms',
3681
3724
  * (data, subscription) => {
3682
3725
  * console.log(`Value of ${subscription.symbol.name} has changed: ${data.value}`);
3683
3726
  * },
@@ -3825,7 +3868,7 @@ class Client extends events_1.default {
3825
3868
  * //Checks if value has changed every 100ms
3826
3869
  * //Callback is called only when the value has changed
3827
3870
  * await client.subscribe({
3828
- * target: 'GVL_Test.ExampleStruct',
3871
+ * target: 'GVL_Subscription.NumericValue_10ms',
3829
3872
  * callback: (data, subscription) => {
3830
3873
  * console.log(`Value of ${subscription.symbol.name} has changed: ${data.value}`);
3831
3874
  * },
@@ -4773,7 +4816,6 @@ class Client extends events_1.default {
4773
4816
  *
4774
4817
  * NOTE: Unlike with {@link readRawByPath}(), this command uses multiple ADS requests for the operation.
4775
4818
  *
4776
- *
4777
4819
  * @example
4778
4820
  * ```js
4779
4821
  * try {
@@ -5042,7 +5084,7 @@ class Client extends events_1.default {
5042
5084
  * @example
5043
5085
  * ```js
5044
5086
  * try {
5045
- * const res = await client.readValue('GVL_Test.ExampleStruct');
5087
+ * const res = await client.readValue('GVL_Read.StandardTypes.INT_');
5046
5088
  * console.log(res.value);
5047
5089
  * } catch (err) {
5048
5090
  * console.log("Error:", err);
@@ -5053,6 +5095,7 @@ class Client extends events_1.default {
5053
5095
  * @param targetOpts Optional target settings that override values in `settings`
5054
5096
  *
5055
5097
  * @template T In Typescript, the data type of the value, for example `readValue<number>(...)` or `readValue<ST_TypedStruct>(...)` (default: `any`)
5098
+ * @throws Throws an error if sending the command fails or if the target responds with an error.
5056
5099
  */
5057
5100
  async readValue(path, targetOpts = {}) {
5058
5101
  if (!this.connection.connected) {
@@ -5073,7 +5116,8 @@ class Client extends events_1.default {
5073
5116
  let dataType;
5074
5117
  try {
5075
5118
  this.debugD(`readValue(): Getting data type for ${path}`);
5076
- dataType = await this.buildDataType(symbol.type, targetOpts);
5119
+ //Also passing size for TC2 pointer/pseudo type support
5120
+ dataType = await this.buildDataType(symbol.type, targetOpts, true, symbol.size);
5077
5121
  }
5078
5122
  catch (err) {
5079
5123
  this.debug(`readValue(): Getting data type for ${path} failed: %o`, err);
@@ -5108,7 +5152,7 @@ class Client extends events_1.default {
5108
5152
  };
5109
5153
  }
5110
5154
  /**
5111
- * Reads variable's value from the target system by a symbol object
5155
+ * Reads variable's value from the target system by a symbol object (acquired using `getSymbol()`)
5112
5156
  * and returns the value as a Javascript object.
5113
5157
  *
5114
5158
  * Returns variable's
@@ -5122,7 +5166,7 @@ class Client extends events_1.default {
5122
5166
  * @example
5123
5167
  * ```js
5124
5168
  * try {
5125
- * const symbol = await client.getSymbol('GVL_Test.ExampleStruct');
5169
+ * const symbol = await client.getSymbol('GVL_Read.StandardTypes.INT_');
5126
5170
  *
5127
5171
  * const res = await client.readValueBySymbol(symbol);
5128
5172
  * console.log(res.value);
@@ -5131,10 +5175,11 @@ class Client extends events_1.default {
5131
5175
  * }
5132
5176
  * ```
5133
5177
  *
5134
- * @param symbol Symbol object (acquired using {@link getSymbol}())
5178
+ * @param symbol Symbol object
5135
5179
  * @param targetOpts Optional target settings that override values in `settings`
5136
5180
  *
5137
5181
  * @template T In Typescript, the data type of the value, for example `readValueBySymbol<number>(...)` or `readValueBySymbol<ST_TypedStruct>(...)` (default: `any`)
5182
+ * @throws Throws an error if sending the command fails or if the target responds with an error.
5138
5183
  */
5139
5184
  async readValueBySymbol(symbol, targetOpts = {}) {
5140
5185
  if (!this.connection.connected) {
@@ -5163,7 +5208,7 @@ class Client extends events_1.default {
5163
5208
  * example: true
5164
5209
  * };
5165
5210
  *
5166
- * const res = await client.writeValue('GVL_Test.ExampleStruct', value);
5211
+ * const res = await client.writeValue('GVL_Read.StandardTypes.INT_', value);
5167
5212
  * } catch (err) {
5168
5213
  * console.log("Error:", err);
5169
5214
  * }
@@ -5172,9 +5217,10 @@ class Client extends events_1.default {
5172
5217
  * @param path Variable path in the PLC (such as `GVL_Test.ExampleStruct`)
5173
5218
  * @param value Value to write
5174
5219
  * @param targetOpts Optional target settings that override values in `settings`
5175
- * @param autoFill If set and the data type is a container (`STRUCT`, `FUNCTION_BLOCK` etc.), missing properties are automatically set to default values (usually `0` or `''`).
5220
+ * @param autoFill If set and the data type is a container (`STRUCT`, `FUNCTION_BLOCK` etc.), missing properties are automatically set to active values read from target (kept as-is).
5176
5221
  *
5177
5222
  * @template T In Typescript, the data type of the value, for example `writeValue<number>(...)` or `writeValue<ST_TypedStruct>(...)`
5223
+ * @throws Throws an error if sending the command fails or if the target responds with an error.
5178
5224
  */
5179
5225
  async writeValue(path, value, autoFill = false, targetOpts = {}) {
5180
5226
  if (!this.connection.connected) {
@@ -5195,7 +5241,8 @@ class Client extends events_1.default {
5195
5241
  let dataType;
5196
5242
  try {
5197
5243
  this.debugD(`writeValue(): Getting data type for ${path}`);
5198
- dataType = await this.buildDataType(symbol.type, targetOpts);
5244
+ //Also passing size for TC2 pointer/pseudo type support
5245
+ dataType = await this.buildDataType(symbol.type, targetOpts, true, symbol.size);
5199
5246
  }
5200
5247
  catch (err) {
5201
5248
  this.debug(`writeValue(): Getting data type for ${path} failed: %o`, err);
@@ -5253,20 +5300,37 @@ class Client extends events_1.default {
5253
5300
  };
5254
5301
  }
5255
5302
  /**
5256
- * **TODO - DOCUMENTATION ONGOING**
5303
+ * Writes variable's value to the target system by a symbol object (acquired using `getSymbol()`).
5304
+ * Converts the value from a Javascript object to a raw value.
5305
+ *
5306
+ * Returns variable's
5307
+ * - converted value
5308
+ * - raw value
5309
+ * - data type
5310
+ * - symbol
5311
+ *
5312
+ * **NOTE:** Do not use `autoFill` for `UNION` types, it doesn't work correctly.
5257
5313
  *
5258
- * Writes a value by symbol. Converts the value from a Javascript object to a raw value.
5314
+ * **NOTE:** This requires that the target is a PLC runtime or has equivalent ADS protocol support.
5259
5315
  *
5260
- * Returns the converted value, the raw value, the data type and the symbol.
5316
+ * @example
5317
+ * ```js
5318
+ * try {
5319
+ * const symbol = await client.getSymbol('GVL_Read.StandardTypes.INT_');
5261
5320
  *
5262
- * **NOTE:** Do not use `autoFill` for `UNION` types, it works without errors but the result isn't probably the desired one
5321
+ * const res = await client.writeValueBySymbol(symbol, 32767);
5322
+ * } catch (err) {
5323
+ * console.log("Error:", err);
5324
+ * }
5325
+ * ```
5263
5326
  *
5264
- * @param symbol Symbol (acquired using `getSymbol()`)
5327
+ * @param symbol Symbol object
5265
5328
  * @param value Value to write
5266
5329
  * @param targetOpts Optional target settings that override values in `settings`
5267
- * @param autoFill If true and data type is a container (`STRUCT`, `FUNCTION_BLOCK` etc.), missing properties are automatically **set to default values** (usually `0` or `''`)
5330
+ * @param autoFill If set and the data type is a container (`STRUCT`, `FUNCTION_BLOCK` etc.), missing properties are automatically set to active values read from target (kept as-is).
5268
5331
  *
5269
5332
  * @template T In Typescript, the data type of the value, for example `writeValue<number>(...)` or `writeValue<ST_TypedStruct>(...)`
5333
+ * @throws Throws an error if sending the command fails or if the target responds with an error.
5270
5334
  */
5271
5335
  async writeValueBySymbol(symbol, value, autoFill = false, targetOpts = {}) {
5272
5336
  if (!this.connection.connected) {
@@ -5275,14 +5339,27 @@ class Client extends events_1.default {
5275
5339
  return this.writeValue(symbol.name, value, autoFill, targetOpts);
5276
5340
  }
5277
5341
  /**
5278
- * **TODO - DOCUMENTATION ONGOING**
5279
- *
5280
5342
  * Returns a default (empty) Javascript object representing provided PLC data type.
5281
5343
  *
5282
- * @param dataType Data type name in the PLC as string (such as `ST_Struct`) or `AdsDataType` object
5344
+ * @example
5345
+ * ```js
5346
+ * try {
5347
+ * const res = await client.getDefaultPlcObject('INT');
5348
+ * console.log(res); //0
5349
+
5350
+ * const res2 = await client.getDefaultPlcObject('Tc2_Standard.TON');
5351
+ * console.log(res2); //{ IN: false, PT: 0, Q: false, ET: 0, M: false, StartTime: 0 }
5352
+ *
5353
+ * } catch (err) {
5354
+ * console.log("Error:", err);
5355
+ * }
5356
+ * ```
5357
+ *
5358
+ * @param dataType Data type name in the PLC as string (such as `ST_Struct`) or data type object (acquired using {@link getDataType}())
5283
5359
  * @param targetOpts Optional target settings that override values in `settings`
5284
5360
  *
5285
- * @template T Typescript data type of the PLC data, for example `readValue<number>(...)` or `readValue<ST_TypedStruct>(...)`
5361
+ * @template T Typescript data type of the PLC data, for example `getDefaultPlcObject<number>(...)` or `getDefaultPlcObject<ST_TypedStruct>(...)`
5362
+ * @throws Throws an error if sending the command fails or if the target responds with an error.
5286
5363
  */
5287
5364
  async getDefaultPlcObject(dataType, targetOpts = {}) {
5288
5365
  if (!this.connection.connected) {
@@ -5306,15 +5383,28 @@ class Client extends events_1.default {
5306
5383
  return value;
5307
5384
  }
5308
5385
  /**
5309
- * **TODO - DOCUMENTATION ONGOING**
5386
+ * Converts raw data to a Javascript object by using the provided data type.
5310
5387
  *
5311
- * Converts a raw byte value to a Javascript object.
5388
+ * @example
5389
+ * ```js
5390
+ * try {
5391
+ * const data = await client.readRaw(16448, 414816, 2);
5392
+ * console.log(data); //<Buffer ff 7f>
5312
5393
  *
5313
- * @param data Raw PLC data as Buffer (read for example with `readRaw()`)
5314
- * @param dataType Data type name in the PLC as string (such as `ST_Struct`) or `AdsDataType` object
5394
+ * const converted = await client.convertFromRaw(data, 'INT');
5395
+ * console.log(converted); //32767
5396
+ *
5397
+ * } catch (err) {
5398
+ * console.log("Error:", err);
5399
+ * }
5400
+ * ```
5401
+ *
5402
+ * @param data Raw data (acquired for example using {@link readRaw}())
5403
+ * @param dataType Data type name in the PLC as string (such as `ST_Struct`) or data type object (acquired using {@link getDataType}())
5315
5404
  * @param targetOpts Optional target settings that override values in `settings`
5316
5405
  *
5317
5406
  * @template T Typescript data type of the PLC data, for example `convertFromRaw<number>(...)` or `convertFromRaw<ST_TypedStruct>(...)`
5407
+ * @throws Throws an error if sending the command fails or if the target responds with an error.
5318
5408
  */
5319
5409
  async convertFromRaw(data, dataType, targetOpts = {}) {
5320
5410
  if (!this.connection.connected) {
@@ -5346,18 +5436,27 @@ class Client extends events_1.default {
5346
5436
  return value;
5347
5437
  }
5348
5438
  /**
5349
- * **TODO - DOCUMENTATION ONGOING**
5439
+ * Converts a Javascript object to raw data by using the provided data type.
5350
5440
  *
5351
- * Converts a Javascript object to raw byte data.
5441
+ * **NOTE:** Do not use `autoFill` for `UNION` types, it doesn't work correctly.
5442
+
5443
+ * @example
5444
+ * ```js
5445
+ * try {
5446
+ * const data = await client.convertToRaw(32767, 'INT');
5447
+ * console.log(data); //<Buffer ff 7f>
5352
5448
  *
5353
- * **NOTE:** Do not use `autoFill` for `UNION` types, it works without errors but the result isn't probably the desired one
5449
+ * } catch (err) {
5450
+ * console.log("Error:", err);
5451
+ * }
5452
+ * ```
5354
5453
  *
5355
- * @param value Javascript object that represents the `dataType` in target system
5356
- * @param dataType Data type name in the PLC as string (such as `ST_Struct`) or `AdsDataType` object
5357
- * @param autoFill If true and data type is a container (`STRUCT`, `FUNCTION_BLOCK` etc.), missing properties are automatically **set to default values** (usually `0` or `''`)
5454
+ * @param value Value to convert
5455
+ * @param dataType Data type name in the PLC as string (such as `ST_Struct`) or data type object (acquired using {@link getDataType}())
5456
+ * @param autoFill autoFill If set and the data type is a container (`STRUCT`, `FUNCTION_BLOCK` etc.), missing properties are automatically set to default values (`0` or empty string).
5358
5457
  * @param targetOpts Optional target settings that override values in `settings`
5359
5458
  *
5360
- * @template T Typescript data type of the PLC data, for example `convertFromRaw<number>(...)` or `convertFromRaw<ST_TypedStruct>(...)`
5459
+ * @throws Throws an error if sending the command fails or if the target responds with an error.
5361
5460
  */
5362
5461
  async convertToRaw(value, dataType, autoFill = false, targetOpts = {}) {
5363
5462
  if (!this.connection.connected) {
@@ -5413,14 +5512,39 @@ class Client extends events_1.default {
5413
5512
  }
5414
5513
  }
5415
5514
  /**
5416
- * **TODO - DOCUMENTATION ONGOING**
5515
+ * Creates a handle to a variable at the target system by variable path (such as `GVL_Test.ExampleStruct`).
5417
5516
  *
5418
- * Creates a variable handle for a PLC symbol by given variable path
5517
+ * The handle can be then used for reading and writing the value.
5419
5518
  *
5420
- * Variable value can be accessed by using the handle with `readRawByHandle()` and `writeRawByHandle()`
5519
+ * Reading and writing dereferenced `POINTER` and `REFERENCE` values is also possible.
5520
+ * See {@link readRawByHandle}() and {@link writeRawByHandle}().
5421
5521
  *
5422
- * @param path Full variable path in the PLC (such as `GVL_Test.ExampleStruct`)
5423
- * @param targetOpts Optional target settings that override values in `settings` (**NOTE:** If used, no caching is available -> possible performance impact)
5522
+ * NOTE: The handle should be deleted after it's no longer needed,
5523
+ * as there is a limited amount of handles available. See {@link deleteVariableHandle}().
5524
+ *
5525
+ * @example
5526
+ * ```js
5527
+ * try {
5528
+ * //POINTER value (Note the dereference operator ^)
5529
+ * const handle1 = await client.createVariableHandle('GVL_Read.ComplexTypes.POINTER_^');
5530
+ * const value = await client.readRawByHandle(handle1);
5531
+ * await client.deleteVariableHandle(handle1);
5532
+ *
5533
+ * const handle2 = await client.createVariableHandle('GVL_Read.StandardTypes.INT_');
5534
+ * const value2 = await client.readRawByHandle(handle2);
5535
+ * await client.deleteVariableHandle(handle2);
5536
+ *
5537
+ * //Now you use convertFromRaw() to get actual values
5538
+ *
5539
+ * } catch (err) {
5540
+ * console.log("Error:", err);
5541
+ * }
5542
+ * ```
5543
+ *
5544
+ * @param path Variable path in the PLC to read (such as `GVL_Test.ExampleStruct`)
5545
+ * @param targetOpts Optional target settings that override values in `settings`
5546
+ *
5547
+ * @throws Throws an error if sending the command fails or if the target responds with an error.
5424
5548
  */
5425
5549
  async createVariableHandle(path, targetOpts = {}) {
5426
5550
  if (!this.connection.connected) {
@@ -5478,18 +5602,44 @@ class Client extends events_1.default {
5478
5602
  }
5479
5603
  }
5480
5604
  /**
5481
- * **TODO - DOCUMENTATION ONGOING**
5605
+ * Sends multiple {@link createVariableHandle}() commands in one ADS packet.
5606
+ *
5607
+ * Creates a handle to a variable at the target system by variable path (such as `GVL_Test.ExampleStruct`).
5608
+ *
5609
+ * The handle can be then used for reading and writing the value.
5482
5610
  *
5483
- * Sends multiple createVariableHandle() commands in one ADS packet
5611
+ * Reading and writing dereferenced `POINTER` and `REFERENCE` values is also possible.
5612
+ * See {@link readRawByHandle}() and {@link writeRawByHandle}().
5484
5613
  *
5485
- * Creates a variable handle for a PLC symbol by given variable path
5614
+ * NOTE: The handle should be deleted after it's no longer needed,
5615
+ * as there is a limited amount of handles available. See {@link deleteVariableHandle}().
5486
5616
  *
5487
- * Variable value can be accessed by using the handle with `readRawByHandle()` and `writeRawByHandle()`
5617
+ * Uses ADS sum command under the hood (better and faster performance).
5618
+ * See [Beckhoff Information System](https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_adsdll2/9007199379576075.html&id=9180083787138954512) for more info.
5619
+ *
5620
+ * @example
5621
+ * ```js
5622
+ * try {
5623
+ * const results = await client.createVariableHandleMulti([
5624
+ * 'GVL_Read.StandardTypes.INT_',
5625
+ * 'GVL_Read.StandardTypes.REAL_'
5626
+ * ]);
5488
5627
  *
5489
- * Uses ADS sum command under the hood (better perfomance)
5628
+ * if(results[0].success) {
5629
+ * console.log(`First handle: ${results[0].handle}`);
5630
+ * } else {
5631
+ * console.log(`Creating first handle failed: ${results[0].errorStr}`);
5632
+ * }
5490
5633
  *
5491
- * @param paths Array of full variable paths in the PLC (such as `GVL_Test.ExampleStruct`)
5634
+ * } catch (err) {
5635
+ * console.log("Error:", err);
5636
+ * }
5637
+ * ```
5638
+ *
5639
+ * @param paths Array of variable paths in the PLC to read (such as `GVL_Test.ExampleStruct`)
5492
5640
  * @param targetOpts Optional target settings that override values in `settings`
5641
+ *
5642
+ * @throws Throws an error if sending the command fails or if the target responds with an error.
5493
5643
  */
5494
5644
  async createVariableHandleMulti(paths, targetOpts = {}) {
5495
5645
  if (!this.connection.connected) {
@@ -5594,12 +5744,26 @@ class Client extends events_1.default {
5594
5744
  }
5595
5745
  }
5596
5746
  /**
5597
- * **TODO - DOCUMENTATION ONGOING**
5747
+ * Deletes a variable handle that was previously created
5748
+ * using {@link createVariableHandle}().
5749
+ *
5750
+ * @example
5751
+ * ```js
5752
+ * try {
5753
+ * const handle = createVariableHandle(...);
5598
5754
  *
5599
- * Deletes a variable handle that was previously created using `createVariableHandle()`
5755
+ * //After use, deleting the handle
5756
+ * await client.deleteVariableHandle(handle);
5757
+ *
5758
+ * } catch (err) {
5759
+ * console.log("Error:", err);
5760
+ * }
5761
+ * ```
5600
5762
  *
5601
5763
  * @param handle Variable handle to delete
5602
- * @param targetOpts Optional target settings that override values in `settings` (**NOTE:** If used, no caching is available -> possible performance impact)
5764
+ * @param targetOpts Optional target settings that override values in `settings`
5765
+ *
5766
+ * @throws Throws an error if sending the command fails or if the target responds with an error.
5603
5767
  */
5604
5768
  async deleteVariableHandle(handle, targetOpts = {}) {
5605
5769
  if (!this.connection.connected) {
@@ -5637,16 +5801,38 @@ class Client extends events_1.default {
5637
5801
  }
5638
5802
  }
5639
5803
  /**
5640
- * **TODO - DOCUMENTATION ONGOING**
5804
+ * Sends multiple {@link deleteVariableHandle}() commands in one ADS packet.
5641
5805
  *
5642
- * Sends multiple deleteVariableHandle() commands in one ADS packet
5806
+ * Deletes a variable handle that was previously created
5807
+ * using {@link createVariableHandle}().
5643
5808
  *
5644
- * Deletes a variable handle that was previously created using `createVariableHandle()`
5809
+ * Uses ADS sum command under the hood (better and faster performance).
5810
+ * See [Beckhoff Information System](https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_adsdll2/9007199379576075.html&id=9180083787138954512) for more info.
5811
+ *
5812
+ * @example
5813
+ * ```js
5814
+ * try {
5815
+ * const handle1 = createVariableHandle(...);
5816
+ * const handle2 = createVariableHandle(...);
5817
+ *
5818
+ * //After use, deleting the handles
5819
+ * const results = await client.deleteVariableHandleMulti([handle1, handle2]);
5820
+ *
5821
+ * if(results[0].success) {
5822
+ * console.log(`First deleted`);
5823
+ * } else {
5824
+ * console.log(`Deleting first handle failed: ${results[0].errorStr}`);
5825
+ * }
5645
5826
  *
5646
- * Uses ADS sum command under the hood (better performance)
5827
+ * } catch (err) {
5828
+ * console.log("Error:", err);
5829
+ * }
5830
+ * ```
5647
5831
  *
5648
5832
  * @param handles Array of variable handles to delete
5649
5833
  * @param targetOpts Optional target settings that override values in `settings`
5834
+ *
5835
+ * @throws Throws an error if sending the command fails or if the target responds with an error.
5650
5836
  */
5651
5837
  async deleteVariableHandleMulti(handles, targetOpts = {}) {
5652
5838
  if (!this.connection.connected) {
@@ -5718,13 +5904,24 @@ class Client extends events_1.default {
5718
5904
  }
5719
5905
  }
5720
5906
  /**
5721
- * **TODO - DOCUMENTATION ONGOING**
5907
+ * Reads raw data from the target system by a previously created variable handle (acquired using {@link createVariableHandle}())
5722
5908
  *
5723
- * Reads raw byte data from the target system by previously created variable handle
5909
+ * @example
5910
+ * ```js
5911
+ * try {
5912
+ * const handle = await client.createVariableHandle('GVL_Read.StandardTypes.INT_'');
5913
+ * const value = await client.readRawByHandle(handle);
5914
+ * await client.deleteVariableHandle(handle);
5724
5915
  *
5916
+ * } catch (err) {
5917
+ * console.log("Error:", err);
5918
+ * }
5919
+ * ```
5725
5920
  * @param handle Variable handle
5726
5921
  * @param size Optional data length to read (bytes) - as default, size in handle is used if available. Uses 0xFFFFFFFF as fallback.
5727
- * @param targetOpts Optional target settings that override values in `settings` (**NOTE:** If used, no caching is available -> possible performance impact)
5922
+ * @param targetOpts Optional target settings that override values in `settings`
5923
+ *
5924
+ * @throws Throws an error if sending the command fails or if the target responds with an error.
5728
5925
  */
5729
5926
  async readRawByHandle(handle, size, targetOpts = {}) {
5730
5927
  if (!this.connection.connected) {
@@ -5748,13 +5945,28 @@ class Client extends events_1.default {
5748
5945
  }
5749
5946
  }
5750
5947
  /**
5751
- * **TODO - DOCUMENTATION ONGOING**
5948
+ * Writes raw data to the target system by a previously created variable handle (acquired using {@link createVariableHandle}())
5949
+ *
5950
+ * @example
5951
+ * ```js
5952
+ * try {
5953
+ * const value = await client.convertToRaw(32767, 'INT');
5954
+ * console.log(value); //<Buffer ff 7f>
5752
5955
  *
5753
- * Writes raw byte data to the target system by previously created variable handle
5956
+ * const handle = await client.createVariableHandle('GVL_Read.StandardTypes.INT_');
5957
+ * await client.writeRawByHandle(handle, value);
5958
+ * await client.deleteVariableHandle(handle);
5959
+ *
5960
+ * } catch (err) {
5961
+ * console.log("Error:", err);
5962
+ * }
5963
+ * ```
5754
5964
  *
5755
5965
  * @param handle Variable handle
5756
5966
  * @param value Data to write
5757
- * @param targetOpts Optional target settings that override values in `settings` (**NOTE:** If used, no caching is available -> possible performance impact)
5967
+ * @param targetOpts Optional target settings that override values in `settings`
5968
+ *
5969
+ * @throws Throws an error if sending the command fails or if the target responds with an error.
5758
5970
  */
5759
5971
  async writeRawByHandle(handle, value, targetOpts = {}) {
5760
5972
  if (!this.connection.connected) {
@@ -5772,12 +5984,23 @@ class Client extends events_1.default {
5772
5984
  }
5773
5985
  }
5774
5986
  /**
5775
- * **TODO - DOCUMENTATION ONGOING**
5987
+ * Reads raw data from the target system by a symbol object (acquired using `getSymbol()`)
5776
5988
  *
5777
- * Reads raw data by symbol
5989
+ * @example
5990
+ * ```js
5991
+ * try {
5992
+ * const symbol = await client.getSymbol('GVL_Read.StandardTypes.INT_');
5993
+ * const value = await client.readRawBySymbol(symbol);
5778
5994
  *
5779
- * @param symbol Symbol (acquired using `getSymbol()`)
5780
- * @param targetOpts Optional target settings that override values in `settings` (**NOTE:** If used, no caching is available -> possible performance impact)
5995
+ * } catch (err) {
5996
+ * console.log("Error:", err);
5997
+ * }
5998
+ * ```
5999
+ *
6000
+ * @param symbol Symbol
6001
+ * @param targetOpts Optional target settings that override values in `settings`
6002
+ *
6003
+ * @throws Throws an error if sending the command fails or if the target responds with an error.
5781
6004
  */
5782
6005
  async readRawBySymbol(symbol, targetOpts = {}) {
5783
6006
  if (!this.connection.connected) {
@@ -5795,13 +6018,27 @@ class Client extends events_1.default {
5795
6018
  }
5796
6019
  }
5797
6020
  /**
5798
- * **TODO - DOCUMENTATION ONGOING**
6021
+ * Writes raw data to the target system by a symbol object (acquired using `getSymbol()`)
6022
+ *
6023
+ * @example
6024
+ * ```js
6025
+ * try {
6026
+ * const value = await client.convertToRaw(32767, 'INT');
6027
+ * console.log(value); //<Buffer ff 7f>
5799
6028
  *
5800
- * Writes raw data by symbol
6029
+ * const symbol = await client.getSymbol('GVL_Read.StandardTypes.INT_');
6030
+ * await client.writeRawBySymbol(symbol, value);
5801
6031
  *
5802
- * @param symbol Symbol (acquired using `getSymbol()`)
6032
+ * } catch (err) {
6033
+ * console.log("Error:", err);
6034
+ * }
6035
+ * ```
6036
+ *
6037
+ * @param symbol Symbol
5803
6038
  * @param value Data to write
5804
6039
  * @param targetOpts Optional target settings that override values in `settings`
6040
+ *
6041
+ * @throws Throws an error if sending the command fails or if the target responds with an error.
5805
6042
  */
5806
6043
  async writeRawBySymbol(symbol, value, targetOpts = {}) {
5807
6044
  if (!this.connection.connected) {
@@ -5818,21 +6055,40 @@ class Client extends events_1.default {
5818
6055
  }
5819
6056
  }
5820
6057
  /**
5821
- * **TODO - DOCUMENTATION ONGOING**
6058
+ * Invokes a function block RPC method on the target system.
5822
6059
  *
5823
- * Invokes/calls a function block RPC method from PLC
6060
+ * Returns the return value of the method and outputs (if any).
5824
6061
  *
5825
- * Returns method return value and/or outputs (if any)
6062
+ * NOTE: In the PLC, `{attribute 'TcRpcEnable'}` is required above the `METHOD` definition.
5826
6063
  *
5827
- * For RPC support, the method needs to have `{attribute 'TcRpcEnable'}` attribute above the `METHOD` definition
6064
+ * @example
6065
+ * ```js
6066
+ * try {
6067
+ * const res = await client.invokeRpcMethod('GVL_RPC.RpcBlock', 'Calculator', {
6068
+ * Value1: 1,
6069
+ * Value2: 123
6070
+ * });
6071
+ *
6072
+ * console.log(res);
6073
+ * //{
6074
+ * // returnValue: true,
6075
+ * // outputs: { Sum: 124, Product: 123, Division: 0.008130080997943878 }
6076
+ * //}
5828
6077
  *
5829
- * @param path Full function block instance path in the PLC (such as `GVL_Test.ExampleBlock`)
5830
- * @param method Function block method name to call
5831
- * @param parameters Function block method parameters (inputs) (if any)
6078
+ * } catch (err) {
6079
+ * console.log("Error:", err);
6080
+ * }
6081
+ * ```
6082
+ *
6083
+ * @param path Variable path in the PLC of the function block instance (such as `GVL_Test.ExampleBlock`)
6084
+ * @param method Function block method name
6085
+ * @param parameters Method parameters (inputs) (if any)
5832
6086
  * @param targetOpts Optional target settings that override values in `settings`
5833
6087
  *
5834
6088
  * @template T Typescript data type of the method return value, for example `invokeRpcMethod<number>(...)` or `invokeRpcMethod<ST_TypedStruct>(...)`
5835
6089
  * @template U Typescript data type of the method outputs object, for example `invokeRpcMethod<number, ST_TypedStruct>(...)`
6090
+ *
6091
+ * @throws Throws an error if sending the command fails or if the target responds with an error.
5836
6092
  */
5837
6093
  async invokeRpcMethod(path, method, parameters = {}, targetOpts = {}) {
5838
6094
  if (!this.connection.connected) {