ads-client 1.14.2 → 1.14.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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,31 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [1.14.4] - 03.10.2023
8
+ ### Changed
9
+ - Bug fix: Changed RPC method flags from 16-bit to 32-bit
10
+ - Bug fix: Fix RPC method parsing in TwinCAT 4026
11
+
12
+ See [PR #127](https://github.com/jisotalo/ads-client/pull/127) for details.
13
+
14
+ Thank you [icon-bobk](https://github.com/icon-bobk) for contribution!
15
+
16
+ ## [1.14.3] - 23.09.2023
17
+ ### Changed
18
+ - Bug fix: Some TwinCAT 2 devices (such as BK9050) do not send data length if answering with error code
19
+ - This caused `RangeError: Index out of range` exception as there wasn't enough bytes received
20
+ - See [issue #116](https://github.com/jisotalo/ads-client/issues/116)
21
+ - Bug fix: If using older Node.js versions such as 8.x, connection lost could have caused unhandled exception
22
+ - Reason was `catch {}` which isn't supported in old versions
23
+ - See [issue #116](https://github.com/jisotalo/ads-client/issues/116)
24
+
25
+ ### Added
26
+ - Updated readme to include information about TypeScript types
27
+ - Thanks to [Christian Rishøj](https://github.com/crishoj)
28
+ - Updated readme with FAQ about TwinCAT 2 low-end devices
29
+ - Updated readme about v2 development
30
+ - Added option to run tests with usermode runtime AmsNetId (`192.168.4.1.1.1`) instead of localhost (`npm run test-um`)
31
+
7
32
  ## [1.14.2] - 02.05.2023
8
33
  ### Changed
9
34
  - Bug fix: `ADS_DATA_TYPE_FLAGS` (`dataType.flags`) were parsed incorrectly.
package/README.md CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
 
4
4
  [![npm version](https://img.shields.io/npm/v/ads-client)](https://www.npmjs.org/package/ads-client)
5
- [![Donate](https://img.shields.io/badge/Donate-PayPal-yellow)](https://www.paypal.com/donate/?business=KUWBXXCVGZZME&no_recurring=0&currency_code=EUR)
6
5
  [![GitHub](https://img.shields.io/badge/View%20on-GitHub-brightgreen)](https://github.com/jisotalo/ads-client)
7
6
  [![License](https://img.shields.io/github/license/jisotalo/ads-client)](https://choosealicense.com/licenses/mit/)
8
7
 
@@ -10,16 +9,25 @@ Beckhoff TwinCAT ADS client library for Node.js (unofficial). Connects to Beckho
10
9
 
11
10
  Coded from scratch using [TwinCAT ADS specification](https://infosys.beckhoff.com/content/1033/tc3_ads_intro/116157835.html?id=124964102706356243) and [Beckhoff.TwinCAT.Ads nuget package](https://www.nuget.org/packages/Beckhoff.TwinCAT.Ads/5.0.0-preview6). Inspiration from similar projects like [node-ads](https://www.npmjs.com/package/node-ads), [beckhoff-js](https://www.npmjs.com/package/beckhoff-js) and [iecstruct](https://www.npmjs.com/package/iecstruct).
12
11
 
13
- There is automatically created documentation available at https://jisotalo.github.io/ads-client/
12
+ There is automatically created documentation available at https://jisotalo.fi/ads-client/
13
+
14
+ # Version 2 will be released soon
15
+
16
+ The 1.4.4 is the the last version for v1, unless some bugs need fixing.
17
+
18
+ <span style="color:red; font-weight:bold;">It might be a good idea to use the version 2 beta for new projects. It will no longer have breaking changes and it's basically ready!</span>
14
19
 
15
- # Project status
16
- This project is currently "ready". It's maintained actively and used in projects by the author and others (also lot's of commercial projects)
20
+ See [`v2-dev`](https://github.com/jisotalo/ads-client/tree/v2-dev) branch for more info. It's a full rewrite in in TypeScript and it can be installed from npm (`npm i ads-client@beta`).
17
21
 
18
- Bugs are fixed if found and new features can be added. Please let me know if you have any ideas!
22
+ # Supporting
19
23
 
20
- And if you want you can buy me a beer using PayPal :)
24
+ If you want to support my work, you can buy me a coffee!
25
+
26
+ <a href="https://www.buymeacoffee.com/jisotalo" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-blue.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" ></a>
27
+
28
+ [![Donate](https://img.shields.io/badge/Donate-PayPal-yellow)](https://www.paypal.com/donate/?business=KUWBXXCVGZZME&no_recurring=0&currency_code=EUR)
21
29
 
22
- [![Donate](https://img.shields.io/badge/Donate%20a%20beer!-PayPal-yellow)](https://www.paypal.com/donate/?business=KUWBXXCVGZZME&no_recurring=0&currency_code=EUR)
30
+ If you need help with integrating the ads-client, I'm available for coding work with invoicing. Please send me email!
23
31
 
24
32
 
25
33
  # Using Node-RED?
@@ -27,68 +35,94 @@ Check out the [node-red-contrib-ads-client](https://www.npmjs.com/package/node-r
27
35
 
28
36
 
29
37
  # Table of contents
38
+ - [ads-client](#ads-client)
39
+ - [Version 2 will be released soon](#version-2-will-be-released-soon)
40
+ - [Supporting](#supporting)
41
+ - [Using Node-RED?](#using-node-red)
42
+ - [Table of contents](#table-of-contents)
30
43
  - [Installation](#installation)
31
44
  - [Features](#features)
32
45
  - [Supported and tested platforms](#supported-and-tested-platforms)
33
46
  - [Connection setups and possibilities](#connection-setups-and-possibilities)
47
+ - [Setup 1 - Connect from Windows PC to the PLC](#setup-1---connect-from-windows-pc-to-the-plc)
48
+ - [Setup 2 - Connecting from Unix/Windows/etc. system to the PLC](#setup-2---connecting-from-unixwindowsetc-system-to-the-plc)
49
+ - [Setup 3 - Connecting from any Node.js supported system to the PLC](#setup-3---connecting-from-any-nodejs-supported-system-to-the-plc)
50
+ - [Setup 4 - Connect to the localhost (PLC and client on the same machine)](#setup-4---connect-to-the-localhost-plc-and-client-on-the-same-machine)
34
51
  - [Enabling localhost support on TwinCAT 3](#enabling-localhost-support-on-twincat-3)
35
52
  - [IMPORTANT: Writing STRUCT variables](#important-writing-struct-variables)
36
53
  - [IMPORTANT: Things to know when using with TwinCAT 2](#important-things-to-know-when-using-with-twincat-2)
54
+ - [TwinCAT 2 first PLC runtime ADS port is 801 instead of 851](#twincat-2-first-plc-runtime-ads-port-is-801-instead-of-851)
55
+ - [Variable names are returned in UPPERCASE on TC2 systems](#variable-names-are-returned-in-uppercase-on-tc2-systems)
56
+ - [Global variable paths are given different on TC2](#global-variable-paths-are-given-different-on-tc2)
57
+ - [InvokeRpcMethod is not possible on TC2](#invokerpcmethod-is-not-possible-on-tc2)
37
58
  - [Connecting to systems without PLC runtime](#connecting-to-systems-without-plc-runtime)
38
59
  - [Getting started](#getting-started)
39
- * [Data types used in getting started](#data-types-used-in-getting-started)
40
- * [Creating a new Client instance](#creating-a-new-client-instance)
41
- * [Available settings](#available-settings)
42
- * [Connecting and disconnecting](#connecting-and-disconnecting)
43
- * [Reading any type PLC variable](#reading-any-type-plc-variable)
44
- + [Example: Reading `INT` type variable](#example-reading-int-type-variable)
45
- + [Example: Reading `STRING` type variable](#example-reading-string-type-variable)
46
- + [Example: Reading `ENUM` type variable](#example-reading-enum-type-variable)
47
- + [Example: Reading `STRUCT` type variable](#example-reading-struct-type-variable)
48
- + [Example: Reading `ARRAY OF INT` type variable](#example-reading-array-of-int-type-variable)
49
- + [Example: Reading `ARRAY OF STRUCT` type variable](#example-reading-array-of-struct-type-variable)
50
- + [Example: Reading `FUNCTION BLOCK` type variable](#example-reading-function-block-type-variable)
51
- * [Writing any type PLC variable](#writing-any-type-plc-variable)
52
- + [Example: Writing `INT` type variable](#example-writing-int-type-variable)
53
- + [Example: Writing `STRING` type variable](#example-writing-string-type-variable)
54
- + [Example: Writing `ENUM` type variable](#example-writing-enum-type-variable)
55
- + [Example: Writing `STRUCT` type variable](#example-writing-struct-type-variable)
56
- + [Example: Writing `STRUCT` type variable (with autoFill parameter)](#example-writing-struct-type-variable-with-autofill-parameter-)
57
- + [Example: Writing `ARRAY OF INT` type variable](#example-writing-array-of-int-type-variable)
58
- + [Example: Writing `ARRAY of STRUCT` type variable](#example-writing-array-of-struct-type-variable)
59
- + [Example: Writing `FUNCTION BLOCK` type variable](#example-writing-function-block-type-variable)
60
- * [Subscribing to PLC variables (device notifications)](#subscribing-to-plc-variables-device-notifications-)
61
- + [Subcribe to variable value (on-change)](#subcribe-to-variable-value-on-change-)
62
- + [Subcribe to variable value (cyclic)](#subcribe-to-variable-value-cyclic-)
63
- * [Reading and writing raw data](#reading-and-writing-raw-data)
64
- + [Getting symbol index group, offset and size](#getting-symbol-index-group-offset-and-size)
65
- + [Reading a single raw value](#reading-a-single-raw-value)
66
- + [Writing a single raw value](#writing-a-single-raw-value)
67
- + [Reading multiple raw values](#reading-multiple-raw-values)
68
- + [Writing multiple raw values](#writing-multiple-raw-values)
69
- + [Creating a variable handle and reading a raw value](#creating-a-variable-handle-and-reading-a-raw-value)
70
- + [Creating a variable handle and writing a raw value](#creating-a-variable-handle-and-writing-a-raw-value)
71
- + [Creating and deleting multiple variable handles](#creating-and-deleting-multiple-variable-handles)
72
- + [Converting a raw value to Javascript object](#converting-a-raw-value-to-javascript-object)
73
- + [Converting a Javascript object to raw value](#converting-a-javascript-object-to-raw-value)
74
- * [Reading and writing `POINTER TO` and `REFERENCE TO` variables](#reading-and-writing-pointer-to-and-reference-to-variables)
75
- + [Reading a `REFERENCE TO` value](#reading-a-reference-to-value)
76
- + [Writing a `REFERENCE TO` value](#writing-a-reference-to-value)
77
- + [Reading a `POINTER TO` value](#reading-a-pointer-to-value)
78
- + [Writing a `POINTER TO` value](#writing-a-pointer-to-value)
79
- * [Calling a function block method with parameters using RPC (remote procedure call)](#calling-a-function-block-method-with-parameters-using-rpc-remote-procedure-call-)
80
- + [Calling a simple RPC method](#calling-a-simple-rpc-method)
81
- + [Using structs with RPC methods](#using-structs-with-rpc-methods)
82
- * [Starting and stopping the PLC](#starting-and-stopping-the-plc)
83
- * [Starting and stopping the TwinCAT system](#starting-and-stopping-the-twincat-system)
84
- * [Sending custom ADS commands](#sending-custom-ads-commands)
60
+ - [Data types used in getting started](#data-types-used-in-getting-started)
61
+ - [Creating a new Client instance](#creating-a-new-client-instance)
62
+ - [Available settings](#available-settings)
63
+ - [Connecting and disconnecting](#connecting-and-disconnecting)
64
+ - [Reading any type PLC variable](#reading-any-type-plc-variable)
65
+ - [Example: Reading `INT` type variable](#example-reading-int-type-variable)
66
+ - [Example: Reading `STRING` type variable](#example-reading-string-type-variable)
67
+ - [Example: Reading `ENUM` type variable](#example-reading-enum-type-variable)
68
+ - [Example: Reading `STRUCT` type variable](#example-reading-struct-type-variable)
69
+ - [Example: Reading `ARRAY OF INT` type variable](#example-reading-array-of-int-type-variable)
70
+ - [Example: Reading `ARRAY OF STRUCT` type variable](#example-reading-array-of-struct-type-variable)
71
+ - [Example: Reading `FUNCTION BLOCK` type variable](#example-reading-function-block-type-variable)
72
+ - [Writing any type PLC variable](#writing-any-type-plc-variable)
73
+ - [Example: Writing `INT` type variable](#example-writing-int-type-variable)
74
+ - [Example: Writing `STRING` type variable](#example-writing-string-type-variable)
75
+ - [Example: Writing `ENUM` type variable](#example-writing-enum-type-variable)
76
+ - [Example: Writing `STRUCT` type variable](#example-writing-struct-type-variable)
77
+ - [Example: Writing `STRUCT` type variable (with autoFill parameter)](#example-writing-struct-type-variable-with-autofill-parameter)
78
+ - [Example: Writing `ARRAY OF INT` type variable](#example-writing-array-of-int-type-variable)
79
+ - [Example: Writing `ARRAY of STRUCT` type variable](#example-writing-array-of-struct-type-variable)
80
+ - [Example: Writing `FUNCTION BLOCK` type variable](#example-writing-function-block-type-variable)
81
+ - [Subscribing to PLC variables (device notifications)](#subscribing-to-plc-variables-device-notifications)
82
+ - [Subcribe to variable value (on-change)](#subcribe-to-variable-value-on-change)
83
+ - [Subcribe to variable value (cyclic)](#subcribe-to-variable-value-cyclic)
84
+ - [Reading and writing raw data](#reading-and-writing-raw-data)
85
+ - [Getting symbol index group, offset and size](#getting-symbol-index-group-offset-and-size)
86
+ - [Reading a single raw value](#reading-a-single-raw-value)
87
+ - [Writing a single raw value](#writing-a-single-raw-value)
88
+ - [Reading multiple raw values](#reading-multiple-raw-values)
89
+ - [Writing multiple raw values](#writing-multiple-raw-values)
90
+ - [Creating a variable handle and reading a raw value](#creating-a-variable-handle-and-reading-a-raw-value)
91
+ - [Creating a variable handle and writing a raw value](#creating-a-variable-handle-and-writing-a-raw-value)
92
+ - [Creating and deleting multiple variable handles](#creating-and-deleting-multiple-variable-handles)
93
+ - [Converting a raw value to Javascript object](#converting-a-raw-value-to-javascript-object)
94
+ - [Converting a Javascript object to raw value](#converting-a-javascript-object-to-raw-value)
95
+ - [Reading and writing `POINTER TO` and `REFERENCE TO` variables](#reading-and-writing-pointer-to-and-reference-to-variables)
96
+ - [Reading a `REFERENCE TO` value](#reading-a-reference-to-value)
97
+ - [Writing a `REFERENCE TO` value](#writing-a-reference-to-value)
98
+ - [Reading a `POINTER TO` value](#reading-a-pointer-to-value)
99
+ - [Writing a `POINTER TO` value](#writing-a-pointer-to-value)
100
+ - [Calling a function block method with parameters using RPC (remote procedure call)](#calling-a-function-block-method-with-parameters-using-rpc-remote-procedure-call)
101
+ - [Calling a simple RPC method](#calling-a-simple-rpc-method)
102
+ - [Using structs with RPC methods](#using-structs-with-rpc-methods)
103
+ - [Starting and stopping the PLC](#starting-and-stopping-the-plc)
104
+ - [Starting and stopping the TwinCAT system](#starting-and-stopping-the-twincat-system)
105
+ - [Sending custom ADS commands](#sending-custom-ads-commands)
85
106
  - [Available ads-client events](#available-ads-client-events)
86
- * [Example: Printing to console when PLC runtime state changes:](#example-printing-to-console-when-plc-runtime-state-changes-)
87
- * [Example: Catching an error that is not directly from a method call](#example-catching-an-error-that-is-not-directly-from-a-method-call)
107
+ - [Example: Printing to console when PLC runtime state changes:](#example-printing-to-console-when-plc-runtime-state-changes)
108
+ - [Example: Catching an error that is not directly from a method call](#example-catching-an-error-that-is-not-directly-from-a-method-call)
88
109
  - [Debugging](#debugging)
89
- * [Enabling debug from code](#enabling-debug-from-code)
90
- * [Enabling debugging from terminal](#enabling-debugging-from-terminal)
110
+ - [Enabling debug from code](#enabling-debug-from-code)
111
+ - [Enabling debugging from terminal](#enabling-debugging-from-terminal)
91
112
  - [FAQ](#faq)
113
+ - [Connection is working very badly and lot's of timeouts](#connection-is-working-very-badly-and-lots-of-timeouts)
114
+ - [When using JSON.stringify or similar I'm getting a `TypeError: Do not know how to serialize a BigInt`](#when-using-jsonstringify-or-similar-im-getting-a-typeerror-do-not-know-how-to-serialize-a-bigint)
115
+ - [Can I connect from Raspberry Pi to TwinCAT?](#can-i-connect-from-raspberry-pi-to-twincat)
116
+ - [Receiving ADS error 1808 `Symbol not found` even when it should be found](#receiving-ads-error-1808-symbol-not-found-even-when-it-should-be-found)
117
+ - [Having timeouts and/or 'mailbox is full' errors when sending lot's of ADS commands](#having-timeouts-andor-mailbox-is-full-errors-when-sending-lots-of-ads-commands)
118
+ - [Having problems to connect from OSX or Raspberry Pi to target PLC](#having-problems-to-connect-from-osx-or-raspberry-pi-to-target-plc)
119
+ - [A data type is not found even when it should be](#a-data-type-is-not-found-even-when-it-should-be)
120
+ - [ClientException: Connection failed: Device system manager state read failed](#clientexception-connection-failed-device-system-manager-state-read-failed)
121
+ - [Connection failed (error EADDRNOTAVAIL)](#connection-failed-error-eaddrnotavail)
122
+ - [Problems running ads-client with docker](#problems-running-ads-client-with-docker)
123
+ - [How to connect to PLC that is in CONFIG mode?](#how-to-connect-to-plc-that-is-in-config-mode)
124
+ - [Getting a message `Ads notification received but it has unknown notificationHandle (**). Use unsubscribe() to save resources.`](#getting-a-message-ads-notification-received-but-it-has-unknown-notificationhandle--use-unsubscribe-to-save-resources)
125
+ - [Issues with TwinCAT 2 low-end devices (BK9050, BC9050 etc.)](#issues-with-twincat-2-low-end-devices-bk9050-bc9050-etc)
92
126
  - [Automatic testing](#automatic-testing)
93
127
  - [Documentation](#documentation)
94
128
  - [License](#license)
@@ -101,6 +135,13 @@ Install the [npm package](https://www.npmjs.com/package/ads-client) using npm co
101
135
  npm i ads-client
102
136
  ```
103
137
 
138
+ If you are using TypeScript, install unofficial types using npm command (thanks [Christian Rishøj](https://github.com/crishoj)):
139
+ ```bash
140
+ npm install --save @types/ads-client
141
+ ```
142
+
143
+ *Note: Version 2 under development will be written in 100% TypeScript*
144
+
104
145
  Include the module in your code
105
146
  ```js
106
147
  const ads = require('ads-client')
@@ -1764,12 +1805,17 @@ Solution:
1764
1805
  * When closing application, first unsubscribe from all notifications using `unsubscribeAll()`
1765
1806
  * Use router instead of direct connection, see https://github.com/jisotalo/ads-client/issues/85#issuecomment-1193098519
1766
1807
 
1808
+ ### Issues with TwinCAT 2 low-end devices (BK9050, BC9050 etc.)
1809
+ * You can only use raw commands (such as `readRaw()`, `writeRaw()`, `subscribeRaw()`) as these devices provide no symbols
1810
+ * See [issue 114](https://github.com/jisotalo/ads-client/issues/114) and [issue 116](https://github.com/jisotalo/ads-client/issues/116) for starters
1811
+
1812
+
1767
1813
  # Automatic testing
1768
1814
  Since version 1.14.0 the library has automatic testing using Jest. Idea is to run the tests before updates to make sure everything works OK (this should have been done much earlier...)
1769
1815
 
1770
1816
  Separate PLC project is required for testing, see https://github.com/jisotalo/ads-client-test-plc-project for more project and more info.
1771
1817
 
1772
- Tests are run with command `npm test` (not in npm version, please clone this repository).
1818
+ Tests are run with command `npm test` or `npm run test-um` (usermode runtime) (not in npm version, please clone this repository).
1773
1819
 
1774
1820
  # Documentation
1775
1821
 
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "ads-client",
3
- "version": "1.14.2",
3
+ "version": "1.14.4",
4
4
  "description": "Beckhoff TwinCAT ADS client library for Node.js (unofficial). Connects to Beckhoff TwinCAT automation systems using ADS protocol.",
5
5
  "main": "./src/ads-client.js",
6
6
  "scripts": {
7
7
  "test": "jest --runInBand",
8
+ "test-um": "set ADS_CLIENT_TEST_AMS=192.168.4.1.1.1 && jest --runInBand",
8
9
  "generate-docs": "jsdoc ./src/ads-client.js ./README.md -c ./jsdoc-conf.json -d ./docs/ -t ./node_modules/docdash/"
9
10
  },
10
11
  "keywords": [
package/src/ads-client.js CHANGED
@@ -894,7 +894,7 @@ class Client extends EventEmitter {
894
894
  } catch (err) {
895
895
  return reject(new ClientException(this, 'readSymbol()', `Reading symbol ${variableName} failed: Reading data type failed`, err))
896
896
  }
897
-
897
+
898
898
  //4. Parse the data to javascript object
899
899
  let data = {}
900
900
  try {
@@ -3658,7 +3658,7 @@ function _reconnect(forceDisconnect = false, isReconnecting = false) {
3658
3658
 
3659
3659
  debug(`_reconnect(): Connection and some subscriptions reinitialized. Connection is back.`)
3660
3660
  })
3661
-
3661
+
3662
3662
  this.emit('reconnect')
3663
3663
 
3664
3664
  resolve(res)
@@ -3945,7 +3945,9 @@ async function _onConnectionLost(socketFailure = false) {
3945
3945
  _console.call(this, 'WARNING: Connection was lost and setting autoReconnect=false. Quiting.')
3946
3946
  try {
3947
3947
  await this.disconnect(true)
3948
- } catch { }
3948
+ } catch (err) {
3949
+ debugD(`_onConnectionLost(): Error during disconnecting. Quiting.`)
3950
+ }
3949
3951
 
3950
3952
  return
3951
3953
  }
@@ -3965,7 +3967,7 @@ async function _onConnectionLost(socketFailure = false) {
3965
3967
  //Try to reconnect
3966
3968
  _reconnect.call(this, socketFailure, true)
3967
3969
  .then(res => {
3968
-
3970
+
3969
3971
  //Success -> remove timer
3970
3972
  _clearTimer(this._internals.reconnectionTimer)
3971
3973
 
@@ -3974,7 +3976,7 @@ async function _onConnectionLost(socketFailure = false) {
3974
3976
  //Reconnecting failed
3975
3977
  if (firstTime)
3976
3978
  _console.call(this, `WARNING: Reconnecting failed. Keeping trying in the background every ${this.settings.reconnectInterval} ms...`)
3977
-
3979
+
3978
3980
  //If this is still a valid timer, start over again
3979
3981
  if (this._internals.reconnectionTimer.id === timerId) {
3980
3982
  //Creating a new timer with the same id
@@ -4018,7 +4020,7 @@ function _clearTimer(timerObject) {
4018
4020
  //Increasing timer id
4019
4021
  timerObject.id = timerObject.id < Number.MAX_SAFE_INTEGER ? timerObject.id + 1 : 0;
4020
4022
  }
4021
-
4023
+
4022
4024
 
4023
4025
 
4024
4026
 
@@ -4294,7 +4296,7 @@ function _systemManagerStatePoller() {
4294
4296
  let oldState = this.metaData.systemManagerState
4295
4297
 
4296
4298
  //If the timer has changed, quit here
4297
- if (this._internals.systemManagerStatePoller.id !== timerId){
4299
+ if (this._internals.systemManagerStatePoller.id !== timerId) {
4298
4300
  return
4299
4301
  }
4300
4302
 
@@ -4353,7 +4355,7 @@ function _systemManagerStatePoller() {
4353
4355
  () => poller(this._internals.systemManagerStatePoller.id),
4354
4356
  this.settings.checkStateInterval
4355
4357
  )
4356
-
4358
+
4357
4359
  }
4358
4360
 
4359
4361
 
@@ -4817,6 +4819,7 @@ async function _parseDataType(data) {
4817
4819
 
4818
4820
  //Get method length
4819
4821
  let len = data.readUInt32LE(pos)
4822
+ const methodFinalPos = pos + len;
4820
4823
  pos += 4
4821
4824
 
4822
4825
  //4..7 Version
@@ -4839,33 +4842,33 @@ async function _parseDataType(data) {
4839
4842
  method.reserved = data.readUInt32LE(pos)
4840
4843
  pos += 4
4841
4844
 
4842
- //24..27 Return type GUID
4845
+ //24..39 Return type GUID
4843
4846
  method.returnTypeGuid = data.slice(pos, pos + 16).toString('hex')
4844
4847
  pos += 16
4845
4848
 
4846
- //28..31 Return data type
4849
+ //40..43 Return data type
4847
4850
  method.retunAdsDataType = data.readUInt32LE(pos)
4848
4851
  method.retunAdsDataTypeStr = ADS.ADS_DATA_TYPES.toString(method.retunAdsDataType)
4849
4852
  pos += 4
4850
4853
 
4851
- //27..30 Flags (AdsDataTypeFlags)
4852
- method.flags = data.readUInt16LE(pos)
4854
+ //44..47 Flags
4855
+ method.flags = data.readUInt32LE(pos)
4853
4856
  method.flagsStr = ADS.ADS_DATA_TYPE_FLAGS.toStringArray(method.flags)
4854
4857
  pos += 4
4855
4858
 
4856
- //31..32 Name length
4859
+ //48..49 Name length
4857
4860
  method.nameLength = data.readUInt16LE(pos)
4858
4861
  pos += 2
4859
4862
 
4860
- //33..34 Return type length
4863
+ //50..51 Return type length
4861
4864
  method.returnTypeLength = data.readUInt16LE(pos)
4862
4865
  pos += 2
4863
4866
 
4864
- //35..36 Comment length
4867
+ //52..53 Comment length
4865
4868
  method.commentLength = data.readUInt16LE(pos)
4866
4869
  pos += 2
4867
4870
 
4868
- //37..38 Parameter count
4871
+ //54..55 Parameter count
4869
4872
  method.parameterCount = data.readUInt16LE(pos)
4870
4873
  pos += 2
4871
4874
 
@@ -4953,6 +4956,7 @@ async function _parseDataType(data) {
4953
4956
  method.parameters.push(param)
4954
4957
  }
4955
4958
 
4959
+ pos = methodFinalPos;
4956
4960
  dataType.rpcMethods.push(method)
4957
4961
  }
4958
4962
  }
@@ -5241,7 +5245,7 @@ function _parseJsObjectToBuffer(value, dataType, objectPathStr = '', isArraySubI
5241
5245
  //Struct or array subitem - Go through each subitem
5242
5246
  if ((dataType.arrayData.length === 0 || isArraySubItem) && dataType.subItems.length > 0) {
5243
5247
  buffer = Buffer.alloc(dataType.size)
5244
-
5248
+
5245
5249
  for (const subItem of dataType.subItems) {
5246
5250
  //Try the find the subitem from javascript object
5247
5251
  let key = null
@@ -6040,11 +6044,16 @@ function _parseAdsData(packet, data) {
6040
6044
  case ADS.ADS_COMMAND.ReadWrite:
6041
6045
  case ADS.ADS_COMMAND.Read:
6042
6046
 
6043
-
6044
6047
  //0..3 Ads error number
6045
6048
  ads.errorCode = data.readUInt32LE(pos)
6046
6049
  pos += 4
6047
6050
 
6051
+ if (data.byteLength <= 4) {
6052
+ ads.dataLength = 0
6053
+ ads.data = Buffer.alloc(0)
6054
+ break
6055
+ }
6056
+
6048
6057
  //4..7 Data length (bytes)
6049
6058
  ads.dataLength = data.readUInt32LE(pos)
6050
6059
  pos += 4
@@ -6055,8 +6064,6 @@ function _parseAdsData(packet, data) {
6055
6064
 
6056
6065
  break
6057
6066
 
6058
-
6059
-
6060
6067
  //-------------- Write ---------------
6061
6068
  case ADS.ADS_COMMAND.Write:
6062
6069
 
@@ -6066,8 +6073,6 @@ function _parseAdsData(packet, data) {
6066
6073
 
6067
6074
  break
6068
6075
 
6069
-
6070
-
6071
6076
  //-------------- Device info ---------------
6072
6077
  case ADS.ADS_COMMAND.ReadDeviceInfo:
6073
6078
 
@@ -6077,6 +6082,10 @@ function _parseAdsData(packet, data) {
6077
6082
 
6078
6083
  ads.data = {}
6079
6084
 
6085
+ if (data.byteLength <= 4) {
6086
+ break
6087
+ }
6088
+
6080
6089
  //4 Major version
6081
6090
  ads.data.majorVersion = data.readUInt8(pos)
6082
6091
  pos += 1
@@ -6094,10 +6103,6 @@ function _parseAdsData(packet, data) {
6094
6103
 
6095
6104
  break
6096
6105
 
6097
-
6098
-
6099
-
6100
-
6101
6106
  //-------------- Device status ---------------
6102
6107
  case ADS.ADS_COMMAND.ReadState:
6103
6108
 
@@ -6107,6 +6112,10 @@ function _parseAdsData(packet, data) {
6107
6112
 
6108
6113
  ads.data = {}
6109
6114
 
6115
+ if (data.byteLength <= 4) {
6116
+ break
6117
+ }
6118
+
6110
6119
  //4..5 ADS state
6111
6120
  ads.data.adsState = data.readUInt16LE(pos)
6112
6121
  ads.data.adsStateStr = ADS.ADS_STATE.toString(ads.data.adsState)
@@ -6118,9 +6127,6 @@ function _parseAdsData(packet, data) {
6118
6127
 
6119
6128
  break
6120
6129
 
6121
-
6122
-
6123
-
6124
6130
  //-------------- Add notification ---------------
6125
6131
  case ADS.ADS_COMMAND.AddNotification:
6126
6132
 
@@ -6130,15 +6136,16 @@ function _parseAdsData(packet, data) {
6130
6136
 
6131
6137
  ads.data = {}
6132
6138
 
6139
+ if (data.byteLength <= 4) {
6140
+ break
6141
+ }
6142
+
6133
6143
  //4..7 Notification handle
6134
6144
  ads.data.notificationHandle = data.readUInt32LE(pos)
6135
6145
  pos += 4
6136
6146
 
6137
6147
  break
6138
6148
 
6139
-
6140
-
6141
-
6142
6149
  //-------------- Delete notification ---------------
6143
6150
  case ADS.ADS_COMMAND.DeleteNotification:
6144
6151
 
@@ -6148,8 +6155,6 @@ function _parseAdsData(packet, data) {
6148
6155
 
6149
6156
  break
6150
6157
 
6151
-
6152
-
6153
6158
  //-------------- Notification ---------------
6154
6159
  case ADS.ADS_COMMAND.Notification:
6155
6160
 
@@ -6157,8 +6162,6 @@ function _parseAdsData(packet, data) {
6157
6162
 
6158
6163
  break
6159
6164
 
6160
-
6161
-
6162
6165
  //-------------- WriteControl ---------------
6163
6166
  case ADS.ADS_COMMAND.WriteControl:
6164
6167
 
@@ -6168,7 +6171,6 @@ function _parseAdsData(packet, data) {
6168
6171
 
6169
6172
  break
6170
6173
 
6171
-
6172
6174
  default:
6173
6175
  //Unknown command, return a custom error
6174
6176
  debug(`_parseAdsResponse: Unknown ads command in response: ${packet.ams.adsCommand}`)