ads-client 1.12.2 → 1.13.0
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 +10 -0
- package/README.md +38 -0
- package/package.json +1 -1
- package/src/ads-client.js +32 -28
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,16 @@ 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.13.0] - 27.02.2022
|
|
8
|
+
### Added
|
|
9
|
+
- Added new setting `bareClient`. If it's set, the client will only connect to the target, nothing else
|
|
10
|
+
- No system manager, symbol version, device info and upload info are read
|
|
11
|
+
- Can be used to connect to non-PLC systems such as [ads-server](https://github.com/jisotalo/ads-server) targets and other ADS supported devices
|
|
12
|
+
- Only requirement is that ADS route is available
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- Updated README
|
|
16
|
+
|
|
7
17
|
## [1.12.2] - 12.02.2022
|
|
8
18
|
### Changed
|
|
9
19
|
- Bug fix: `TOD` data type was not regonized on TwinCAT 2 and TwinCAT 3 (TC3 builds <= 4020)
|
package/README.md
CHANGED
|
@@ -29,6 +29,7 @@ Check out the [node-red-contrib-ads-client](https://www.npmjs.com/package/node-r
|
|
|
29
29
|
- [Enabling localhost support on TwinCAT 3](#enabling-localhost-support-on-twincat-3)
|
|
30
30
|
- [IMPORTANT: Writing STRUCT variables](#important-writing-struct-variables)
|
|
31
31
|
- [IMPORTANT: Things to know when using with TwinCAT 2](#important-things-to-know-when-using-with-twincat-2)
|
|
32
|
+
- [Connecting to systems without PLC runtime](#connecting-to-systems-without-plc-runtime)
|
|
32
33
|
- [Getting started](#getting-started)
|
|
33
34
|
* [Data types used in getting started](#data-types-used-in-getting-started)
|
|
34
35
|
* [Creating a new Client instance](#creating-a-new-client-instance)
|
|
@@ -336,6 +337,26 @@ await client.readSymbol('.ExampleSTRUCT') //TwinCAT 2
|
|
|
336
337
|
This is the only one non-working feature as there are no methods in TC2.
|
|
337
338
|
|
|
338
339
|
|
|
340
|
+
# Connecting to systems without PLC runtime
|
|
341
|
+
|
|
342
|
+
Since version 1.13.0 it's possible to connect to systems without PLC runtime and/or system manager using `ads-client`.
|
|
343
|
+
|
|
344
|
+
In previous versions, the client always checked the system state (RUN, CONFIG). However when connecting to different systems (non-PLC systems), there might be no system manager service. With default configuration this causes an error:
|
|
345
|
+
```
|
|
346
|
+
ClientException: Connection failed: Device system manager state read failed
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
By providing `bareClient` setting, the client connects to the router or target and nothing else. After that, the client can be used to read/write data. However, connection losses etc. need to be handled by the user.
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
```js
|
|
353
|
+
const client = new ads.Client({
|
|
354
|
+
targetAmsNetId: '192.168.5.131.3.1',
|
|
355
|
+
targetAdsPort: 1002,
|
|
356
|
+
bareClient: true //NOTE
|
|
357
|
+
})
|
|
358
|
+
```
|
|
359
|
+
|
|
339
360
|
# Getting started
|
|
340
361
|
|
|
341
362
|
This chapter includes some short getting started examples. See the JSDoc [documentation](#documentation) for detailed description of library classes and methods.
|
|
@@ -1623,6 +1644,23 @@ For example, when copying a variable name from TwinCAT online view using CTRL+C,
|
|
|
1623
1644
|
|
|
1624
1645
|
If you have problems, try to read the variable information using `readSymbolInfo()`. The final solution is to read all data types using `readAndCacheDataTypes()` and manually finding the correct type.
|
|
1625
1646
|
|
|
1647
|
+
### ClientException: Connection failed: Device system manager state read failed
|
|
1648
|
+
|
|
1649
|
+
This error indicates that the given AmsnetId didn't contain system manager service (port 10000). If you connect to the PLC system, there is always system manager and PLC runtime(s). However, when connecting to other systems than PLC, it might be that there is no system manager service.
|
|
1650
|
+
|
|
1651
|
+
Solution:
|
|
1652
|
+
- Double check AmsNetId settings (if connecting directly to PLC)
|
|
1653
|
+
- [Set `bareClient` setting to skip all system manager and PLC runtime checks](#connecting-to-systems-without-plc-runtime) (version 1.13.0 ->)
|
|
1654
|
+
|
|
1655
|
+
### Connection failed (error EADDRNOTAVAIL)
|
|
1656
|
+
This could happen if you have manually provided `localAddress` or `localTcpPort` that don't exist.
|
|
1657
|
+
For example, setting localAddress to 192.168.10.1 when the computer has only ethernet interface with IP 192.168.1.1.
|
|
1658
|
+
|
|
1659
|
+
See https://github.com/jisotalo/ads-client/issues/82
|
|
1660
|
+
|
|
1661
|
+
### Problems running ads-client with docker
|
|
1662
|
+
|
|
1663
|
+
- EADDRNOTAVAIL: See above and https://github.com/jisotalo/ads-client/issues/82
|
|
1626
1664
|
|
|
1627
1665
|
# Documentation
|
|
1628
1666
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ads-client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
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": {
|
package/src/ads-client.js
CHANGED
|
@@ -74,6 +74,7 @@ class Client extends EventEmitter {
|
|
|
74
74
|
* @property {number} [connectionDownDelay=5000] - Time (milliseconds) after no successful reading of the system manager state the connection is determined to be lost - Optional (**default**: 5000 ms)
|
|
75
75
|
* @property {boolean} [allowHalfOpen=false] - If true, connect() is successful even if no PLC runtime is found (but target and system manager are available) - Can be useful if it's ok that after connect() the PLC runtime is not immediately available (example: connecting before uploading PLC code and reading data later) - WARNING: If true, reinitializing subscriptions might fail after connection loss.
|
|
76
76
|
* @property {boolean} [disableBigInt=false] - If true, 64 bit integer PLC variables are kept as Buffer objects instead of converting to Javascript BigInt variables (JSON.strigify and libraries that use it have no BigInt support)
|
|
77
|
+
* @property {boolean} [bareClient=false] - If true, only direct ads connection is established (no system manager etc) - Can be used to connect to systems without PLC runtimes etc.
|
|
77
78
|
*/
|
|
78
79
|
|
|
79
80
|
|
|
@@ -102,7 +103,8 @@ class Client extends EventEmitter {
|
|
|
102
103
|
checkStateInterval: 1000,
|
|
103
104
|
connectionDownDelay: 5000,
|
|
104
105
|
allowHalfOpen: false,
|
|
105
|
-
disableBigInt: false
|
|
106
|
+
disableBigInt: false,
|
|
107
|
+
bareClient: false
|
|
106
108
|
}
|
|
107
109
|
}
|
|
108
110
|
|
|
@@ -3396,43 +3398,45 @@ function _connect(isReconnecting = false) {
|
|
|
3396
3398
|
this._internals.socketErrorHandler = _onSocketError.bind(this)
|
|
3397
3399
|
socket.on('error', this._internals.socketErrorHandler)
|
|
3398
3400
|
|
|
3399
|
-
|
|
3400
|
-
//Try to read system manager state - If it's OK, connection is successful to the target
|
|
3401
|
-
await this.readSystemManagerState()
|
|
3402
|
-
_systemManagerStatePoller.call(this)
|
|
3403
|
-
|
|
3404
|
-
} catch (err) {
|
|
3401
|
+
if (this.settings.bareClient !== true) {
|
|
3405
3402
|
try {
|
|
3406
|
-
|
|
3403
|
+
//Try to read system manager state - If it's OK, connection is successful to the target
|
|
3404
|
+
await this.readSystemManagerState()
|
|
3405
|
+
_systemManagerStatePoller.call(this)
|
|
3406
|
+
|
|
3407
3407
|
} catch (err) {
|
|
3408
|
-
|
|
3408
|
+
try {
|
|
3409
|
+
await _disconnect.call(this, false, isReconnecting)
|
|
3410
|
+
} catch (err) {
|
|
3411
|
+
debug(`_connect(): Reading target system manager failed -> Connection closed`)
|
|
3412
|
+
}
|
|
3413
|
+
this.connection.connected = false
|
|
3414
|
+
|
|
3415
|
+
return reject(new ClientException(this, '_connect()', `Connection failed: ${err.message}`, err))
|
|
3409
3416
|
}
|
|
3410
|
-
this.connection.connected = false
|
|
3411
3417
|
|
|
3412
|
-
return reject(new ClientException(this, '_connect()', `Connection failed: ${err.message}`, err))
|
|
3413
|
-
}
|
|
3414
3418
|
|
|
3419
|
+
try {
|
|
3420
|
+
await _reInitializeInternals.call(this)
|
|
3415
3421
|
|
|
3416
|
-
|
|
3417
|
-
|
|
3422
|
+
} catch (err) {
|
|
3423
|
+
if (this.settings.allowHalfOpen !== true) {
|
|
3424
|
+
try {
|
|
3425
|
+
await _disconnect.call(this, false, true)
|
|
3426
|
+
} catch (err) {
|
|
3427
|
+
debug(`_connect(): Connecting to target PLC runtime failed -> Connection closed`)
|
|
3428
|
+
}
|
|
3429
|
+
this.connection.connected = false
|
|
3418
3430
|
|
|
3419
|
-
|
|
3420
|
-
if (this.settings.allowHalfOpen !== true) {
|
|
3421
|
-
try {
|
|
3422
|
-
await _disconnect.call(this, false, true)
|
|
3423
|
-
} catch (err) {
|
|
3424
|
-
debug(`_connect(): Connecting to target PLC runtime failed -> Connection closed`)
|
|
3431
|
+
return reject(new ClientException(this, '_connect()', `Target and system manager found but couldn't connect to the PLC runtime (see settings allowHalfOpen and bareClient): ${err.message}`, err))
|
|
3425
3432
|
}
|
|
3426
|
-
this.connection.connected = false
|
|
3427
3433
|
|
|
3428
|
-
|
|
3434
|
+
//Todo: Redesign this
|
|
3435
|
+
if (this.metaData.systemManagerState.adsState !== ADS.ADS_STATE.Run)
|
|
3436
|
+
_console.call(this, `WARNING: Target is connected but not in RUN mode (mode: ${this.metaData.systemManagerState.adsStateStr}) - connecting to runtime (ADS port ${this.settings.targetAdsPort}) failed`)
|
|
3437
|
+
else
|
|
3438
|
+
_console.call(this, `WARNING: Target is connected but connecting to runtime (ADS port ${this.settings.targetAdsPort}) failed - Check the port number and that the target system state (${this.metaData.systemManagerState.adsStateStr}) is valid.`)
|
|
3429
3439
|
}
|
|
3430
|
-
|
|
3431
|
-
//Todo: Redesign this
|
|
3432
|
-
if (this.metaData.systemManagerState.adsState !== ADS.ADS_STATE.Run)
|
|
3433
|
-
_console.call(this, `WARNING: Target is connected but not in RUN mode (mode: ${this.metaData.systemManagerState.adsStateStr}) - connecting to runtime (ADS port ${this.settings.targetAdsPort}) failed`)
|
|
3434
|
-
else
|
|
3435
|
-
_console.call(this, `WARNING: Target is connected but connecting to runtime (ADS port ${this.settings.targetAdsPort}) failed - Check the port number and that the target system state (${this.metaData.systemManagerState.adsStateStr}) is valid.`)
|
|
3436
3440
|
}
|
|
3437
3441
|
|
|
3438
3442
|
//Listening connection lost events
|