@things-factory/integration-modbus 9.0.0-beta.27 → 9.0.0-beta.29

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.
@@ -0,0 +1,2 @@
1
+ import './modbus-tcp-server';
2
+ import './modbus-tcp';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("./modbus-tcp-server");
4
+ require("./modbus-tcp");
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/engine/connector/index.ts"],"names":[],"mappings":";;AAAA,+BAA4B;AAC5B,wBAAqB","sourcesContent":["import './modbus-tcp-server'\nimport './modbus-tcp'\n"]}
@@ -0,0 +1,7 @@
1
+ import { Connector, Connection } from '@things-factory/integration-base';
2
+ export declare class ModbusTCPServer implements Connector {
3
+ ready(connectionConfigs: any): Promise<void>;
4
+ connect(config: any): Promise<void>;
5
+ disconnect(connection: Connection): Promise<void>;
6
+ get parameterSpec(): any[];
7
+ }
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ModbusTCPServer = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const integration_base_1 = require("@things-factory/integration-base");
6
+ const net_1 = tslib_1.__importDefault(require("net"));
7
+ const modbus = tslib_1.__importStar(require("jsmodbus"));
8
+ class ModbusTCPServer {
9
+ async ready(connectionConfigs) {
10
+ await Promise.all(connectionConfigs.map(this.connect));
11
+ integration_base_1.ConnectionManager.logger.info('modbus-tcp-servers are ready');
12
+ }
13
+ async connect(config) {
14
+ var [host = '0.0.0.0', port = 502] = config.endpoint.split(':');
15
+ const netServer = new net_1.default.Server();
16
+ const server = new modbus.server.TCP(netServer);
17
+ netServer.on('error', console.error);
18
+ netServer.listen(port, host);
19
+ /* default client connection */
20
+ const clientSocket = new net_1.default.Socket();
21
+ const client = new modbus.client.TCP(clientSocket);
22
+ clientSocket.on('error', console.error);
23
+ clientSocket.connect({ host: 'localhost', port });
24
+ client['__server__'] = server;
25
+ integration_base_1.ConnectionManager.addConnectionInstance(config, client);
26
+ integration_base_1.ConnectionManager.logger.info(`modbus-tcp-server connection(${config.name}:${config.endpoint}) is connected`);
27
+ }
28
+ async disconnect(connection) {
29
+ var client = integration_base_1.ConnectionManager.removeConnectionInstance(connection);
30
+ var server = client['__server__'];
31
+ client.socket.end();
32
+ server && server._server.close();
33
+ integration_base_1.ConnectionManager.logger.info(`modbus-tcp-server connection(${connection.name}) is disconnected`);
34
+ }
35
+ get parameterSpec() {
36
+ return [];
37
+ }
38
+ }
39
+ exports.ModbusTCPServer = ModbusTCPServer;
40
+ integration_base_1.ConnectionManager.registerConnector('modbus-tcp-server', new ModbusTCPServer());
41
+ //# sourceMappingURL=modbus-tcp-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modbus-tcp-server.js","sourceRoot":"","sources":["../../../server/engine/connector/modbus-tcp-server.ts"],"names":[],"mappings":";;;;AAAA,uEAA2F;AAC3F,sDAAqB;AACrB,yDAAkC;AAElC,MAAa,eAAe;IAC1B,KAAK,CAAC,KAAK,CAAC,iBAAiB;QAC3B,MAAM,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;QAEtD,oCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAA;IAC/D,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAM;QAClB,IAAI,CAAC,IAAI,GAAG,SAAS,EAAE,IAAI,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAE/D,MAAM,SAAS,GAAG,IAAI,aAAG,CAAC,MAAM,EAAE,CAAA;QAElC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAE/C,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;QACpC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAE5B,+BAA+B;QAC/B,MAAM,YAAY,GAAG,IAAI,aAAG,CAAC,MAAM,EAAE,CAAA;QACrC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QAClD,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;QACvC,YAAY,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;QAEjD,MAAM,CAAC,YAAY,CAAC,GAAG,MAAM,CAAA;QAE7B,oCAAiB,CAAC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAEvD,oCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,QAAQ,gBAAgB,CAAC,CAAA;IAC/G,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,UAAsB;QACrC,IAAI,MAAM,GAAG,oCAAiB,CAAC,wBAAwB,CAAC,UAAU,CAAC,CAAA;QACnE,IAAI,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,CAAA;QAEjC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAA;QACnB,MAAM,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAA;QAEhC,oCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,UAAU,CAAC,IAAI,mBAAmB,CAAC,CAAA;IACnG,CAAC;IAED,IAAI,aAAa;QACf,OAAO,EAAE,CAAA;IACX,CAAC;CACF;AA3CD,0CA2CC;AAED,oCAAiB,CAAC,iBAAiB,CAAC,mBAAmB,EAAE,IAAI,eAAe,EAAE,CAAC,CAAA","sourcesContent":["import { ConnectionManager, Connector, Connection } from '@things-factory/integration-base'\nimport net from 'net'\nimport * as modbus from 'jsmodbus'\n\nexport class ModbusTCPServer implements Connector {\n async ready(connectionConfigs) {\n await Promise.all(connectionConfigs.map(this.connect))\n\n ConnectionManager.logger.info('modbus-tcp-servers are ready')\n }\n\n async connect(config) {\n var [host = '0.0.0.0', port = 502] = config.endpoint.split(':')\n\n const netServer = new net.Server()\n\n const server = new modbus.server.TCP(netServer)\n\n netServer.on('error', console.error)\n netServer.listen(port, host)\n\n /* default client connection */\n const clientSocket = new net.Socket()\n const client = new modbus.client.TCP(clientSocket)\n clientSocket.on('error', console.error)\n clientSocket.connect({ host: 'localhost', port })\n\n client['__server__'] = server\n\n ConnectionManager.addConnectionInstance(config, client)\n\n ConnectionManager.logger.info(`modbus-tcp-server connection(${config.name}:${config.endpoint}) is connected`)\n }\n\n async disconnect(connection: Connection) {\n var client = ConnectionManager.removeConnectionInstance(connection)\n var server = client['__server__']\n\n client.socket.end()\n server && server._server.close()\n\n ConnectionManager.logger.info(`modbus-tcp-server connection(${connection.name}) is disconnected`)\n }\n\n get parameterSpec() {\n return []\n }\n}\n\nConnectionManager.registerConnector('modbus-tcp-server', new ModbusTCPServer())\n"]}
@@ -0,0 +1,17 @@
1
+ import { Connection, Connector } from '@things-factory/integration-base';
2
+ export declare class ModbusTCPConnector implements Connector {
3
+ ready(connectionConfigs: any): Promise<void>;
4
+ checkConnectionInstance(domain: any, connectionName: any): boolean;
5
+ connect(connection: any): Promise<void>;
6
+ disconnect(connection: Connection): Promise<void>;
7
+ get parameterSpec(): {
8
+ type: string;
9
+ name: string;
10
+ label: string;
11
+ property: {
12
+ value: string;
13
+ };
14
+ }[];
15
+ get taskPrefixes(): string[];
16
+ get help(): string;
17
+ }
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ModbusTCPConnector = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const modbus = tslib_1.__importStar(require("jsmodbus"));
6
+ const net_1 = require("net");
7
+ const p_queue_1 = tslib_1.__importDefault(require("p-queue"));
8
+ const promise_socket_1 = tslib_1.__importDefault(require("promise-socket"));
9
+ const integration_base_1 = require("@things-factory/integration-base");
10
+ const utils_1 = require("@things-factory/utils");
11
+ const debug = require('debug')('things-factory:modbus-tcp-connector');
12
+ class ModbusTCPConnector {
13
+ async ready(connectionConfigs) {
14
+ await Promise.all(connectionConfigs.map(this.connect.bind(this)));
15
+ integration_base_1.ConnectionManager.logger.info('modbus-tcp connections are ready');
16
+ }
17
+ checkConnectionInstance(domain, connectionName) {
18
+ var _a;
19
+ try {
20
+ const connection = integration_base_1.ConnectionManager.getConnectionInstanceByName(domain, connectionName);
21
+ return !!(((_a = connection === null || connection === void 0 ? void 0 : connection.client) === null || _a === void 0 ? void 0 : _a.connectionState) !== 'online');
22
+ }
23
+ catch (e) {
24
+ return false;
25
+ }
26
+ }
27
+ async connect(connection) {
28
+ var [host, port = 502] = connection.endpoint.split(':');
29
+ var { params: { keepalive = true } } = connection;
30
+ try {
31
+ /*
32
+ try to keep connecting if keepalive is true
33
+ */
34
+ var clientIdx = 1;
35
+ var connected = false;
36
+ var looped = true;
37
+ while (true) {
38
+ var clientSocket = new net_1.Socket();
39
+ clientSocket = new net_1.Socket();
40
+ var promiseSocket = new promise_socket_1.default(clientSocket);
41
+ var client = new modbus.client.TCP(clientSocket, clientIdx++, 10000);
42
+ clientSocket.on('error', async (ex) => {
43
+ debug(ex);
44
+ integration_base_1.ConnectionManager.logger.error(`modbus tcp connection error: ${ex}`);
45
+ });
46
+ clientSocket.on('close', async () => {
47
+ debug(`modbus tcp connection closed`);
48
+ if (keepalive && !looped) {
49
+ await this.disconnect(connection);
50
+ await this.connect(connection);
51
+ }
52
+ });
53
+ debug(`connecting to ${connection.endpoint}...`);
54
+ looped = true;
55
+ await promiseSocket
56
+ .connect(port, host)
57
+ .then(() => {
58
+ connected = true;
59
+ })
60
+ .catch(ex => {
61
+ promiseSocket && promiseSocket.destroy();
62
+ });
63
+ // if the current connections have the connection with the same name, the current try should be stopped.
64
+ if (!keepalive || connected) {
65
+ looped = false;
66
+ break;
67
+ }
68
+ await (0, utils_1.sleep)(1000);
69
+ }
70
+ var queue = new p_queue_1.default({ concurrency: 1 });
71
+ integration_base_1.ConnectionManager.addConnectionInstance(connection, {
72
+ readModBus: async function (objectType, address, quantity, { logger }) {
73
+ return await queue.add(async () => {
74
+ var response;
75
+ switch (objectType) {
76
+ case 'descrete input':
77
+ response = await client.readDiscreteInputs(address, quantity);
78
+ break;
79
+ case 'input register':
80
+ response = await client.readInputRegisters(address, quantity);
81
+ break;
82
+ case 'holding register':
83
+ response = await client.readHoldingRegisters(address, quantity);
84
+ break;
85
+ default:
86
+ response = await client.readCoils(address, quantity);
87
+ }
88
+ var data = response && response.response._body.valuesAsArray.slice(0, quantity);
89
+ logger.info(`${JSON.stringify(data)}`);
90
+ return {
91
+ data
92
+ };
93
+ });
94
+ },
95
+ writeSingleModBus: async function (objectType, address, value, { logger }) {
96
+ return await queue.add(async () => {
97
+ var response;
98
+ switch (objectType) {
99
+ case 'holding register':
100
+ await client.writeSingleRegister(address, parseInt(value));
101
+ response = await client.readHoldingRegisters(address, 1);
102
+ break;
103
+ default:
104
+ await client.writeSingleCoil(address, !!Number(value));
105
+ response = await client.readCoils(address, 1);
106
+ }
107
+ var data = response && response.response._body.valuesAsArray[0];
108
+ logger.info(data);
109
+ return {
110
+ data
111
+ };
112
+ });
113
+ },
114
+ close: function () {
115
+ queue.clear();
116
+ keepalive = false;
117
+ promiseSocket.destroy();
118
+ }
119
+ });
120
+ integration_base_1.ConnectionManager.logger.info(`modbus-tcp connection(${connection.name}:${connection.endpoint}) is connected`);
121
+ }
122
+ catch (ex) {
123
+ integration_base_1.ConnectionManager.logger.info(`modbus-tcp connection(${connection.name}:${connection.endpoint}) failed to connect`);
124
+ throw ex;
125
+ }
126
+ }
127
+ async disconnect(connection) {
128
+ var { close } = integration_base_1.ConnectionManager.removeConnectionInstance(connection);
129
+ close();
130
+ integration_base_1.ConnectionManager.logger.info(`modbus-tcp connection(${connection.name}) is disconnected`);
131
+ }
132
+ get parameterSpec() {
133
+ return [
134
+ {
135
+ type: 'checkbox',
136
+ name: 'keepalive',
137
+ label: 'keepalive',
138
+ property: {
139
+ value: 'checked'
140
+ }
141
+ }
142
+ ];
143
+ }
144
+ get taskPrefixes() {
145
+ return ['modbus'];
146
+ }
147
+ get help() {
148
+ return 'integration/connector/modbus-tcp';
149
+ }
150
+ }
151
+ exports.ModbusTCPConnector = ModbusTCPConnector;
152
+ integration_base_1.ConnectionManager.registerConnector('modbus-tcp', new ModbusTCPConnector());
153
+ //# sourceMappingURL=modbus-tcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modbus-tcp.js","sourceRoot":"","sources":["../../../server/engine/connector/modbus-tcp.ts"],"names":[],"mappings":"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","sourcesContent":["import * as modbus from 'jsmodbus'\nimport { Socket } from 'net'\nimport PQueue from 'p-queue'\nimport PromiseSocket from 'promise-socket'\n\nimport { Connection, ConnectionManager, Connector } from '@things-factory/integration-base'\nimport { sleep } from '@things-factory/utils'\n\nconst debug = require('debug')('things-factory:modbus-tcp-connector')\n\nexport class ModbusTCPConnector implements Connector {\n async ready(connectionConfigs) {\n await Promise.all(connectionConfigs.map(this.connect.bind(this)))\n\n ConnectionManager.logger.info('modbus-tcp connections are ready')\n }\n\n checkConnectionInstance(domain, connectionName): boolean {\n try {\n const connection = ConnectionManager.getConnectionInstanceByName(domain, connectionName)\n\n return !!(connection?.client?.connectionState !== 'online')\n } catch (e) {\n return false\n }\n }\n\n async connect(connection) {\n var [host, port = 502] = connection.endpoint.split(':')\n var {\n params: { keepalive = true }\n } = connection\n\n try {\n /*\n try to keep connecting if keepalive is true\n */\n var clientIdx = 1\n var connected: boolean = false\n var looped: boolean = true\n while (true) {\n var clientSocket = new Socket()\n clientSocket = new Socket()\n var promiseSocket = new PromiseSocket(clientSocket)\n\n var client = new modbus.client.TCP(clientSocket, clientIdx++, 10000)\n\n clientSocket.on('error', async ex => {\n debug(ex)\n ConnectionManager.logger.error(`modbus tcp connection error: ${ex}`)\n })\n\n clientSocket.on('close', async () => {\n debug(`modbus tcp connection closed`)\n if (keepalive && !looped) {\n await this.disconnect(connection)\n await this.connect(connection)\n }\n })\n\n debug(`connecting to ${connection.endpoint}...`)\n\n looped = true\n await promiseSocket\n .connect(port, host)\n .then(() => {\n connected = true\n })\n .catch(ex => {\n promiseSocket && promiseSocket.destroy()\n })\n\n // if the current connections have the connection with the same name, the current try should be stopped.\n if (!keepalive || connected) {\n looped = false\n break\n }\n\n await sleep(1000)\n }\n\n var queue = new PQueue({ concurrency: 1 })\n ConnectionManager.addConnectionInstance(connection, {\n readModBus: async function (objectType, address, quantity, { logger }) {\n return await queue.add(async () => {\n var response\n\n switch (objectType) {\n case 'descrete input':\n response = await client.readDiscreteInputs(address, quantity)\n break\n case 'input register':\n response = await client.readInputRegisters(address, quantity)\n break\n case 'holding register':\n response = await client.readHoldingRegisters(address, quantity)\n break\n default:\n response = await client.readCoils(address, quantity)\n }\n\n var data = response && response.response._body.valuesAsArray.slice(0, quantity)\n logger.info(`${JSON.stringify(data)}`)\n return {\n data\n }\n })\n },\n writeSingleModBus: async function (objectType, address, value, { logger }) {\n return await queue.add(async () => {\n var response\n\n switch (objectType) {\n case 'holding register':\n await client.writeSingleRegister(address, parseInt(value))\n response = await client.readHoldingRegisters(address, 1)\n break\n default:\n await client.writeSingleCoil(address, !!Number(value))\n response = await client.readCoils(address, 1)\n }\n\n var data = response && response.response._body.valuesAsArray[0]\n logger.info(data)\n return {\n data\n }\n })\n },\n close: function () {\n queue.clear()\n keepalive = false\n promiseSocket.destroy()\n }\n })\n\n ConnectionManager.logger.info(`modbus-tcp connection(${connection.name}:${connection.endpoint}) is connected`)\n } catch (ex) {\n ConnectionManager.logger.info(`modbus-tcp connection(${connection.name}:${connection.endpoint}) failed to connect`)\n throw ex\n }\n }\n\n async disconnect(connection: Connection) {\n var { close } = ConnectionManager.removeConnectionInstance(connection)\n close()\n\n ConnectionManager.logger.info(`modbus-tcp connection(${connection.name}) is disconnected`)\n }\n\n get parameterSpec() {\n return [\n {\n type: 'checkbox',\n name: 'keepalive',\n label: 'keepalive',\n property: {\n value: 'checked'\n }\n }\n ]\n }\n\n get taskPrefixes() {\n return ['modbus']\n }\n\n get help() {\n return 'integration/connector/modbus-tcp'\n }\n}\n\nConnectionManager.registerConnector('modbus-tcp', new ModbusTCPConnector())\n"]}
@@ -0,0 +1,2 @@
1
+ import './connector/index.js';
2
+ import './task/index.js';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("./connector/index.js");
4
+ require("./task/index.js");
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/engine/index.ts"],"names":[],"mappings":";;AAAA,gCAA6B;AAC7B,2BAAwB","sourcesContent":["import './connector/index.js'\nimport './task/index.js'\n"]}
@@ -0,0 +1,2 @@
1
+ import './modbus-read';
2
+ import './modbus-write-single';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("./modbus-read");
4
+ require("./modbus-write-single");
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/engine/task/index.ts"],"names":[],"mappings":";;AAAA,yBAAsB;AACtB,iCAA8B","sourcesContent":["import './modbus-read'\nimport './modbus-write-single'\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const utils_1 = require("@things-factory/utils");
4
+ const integration_base_1 = require("@things-factory/integration-base");
5
+ const debug = require('debug')('things-factory:modbus-read');
6
+ async function modbusRead(step, { logger, domain, data }) {
7
+ var { connection, params: { objectType = 'coil', address, quantity = 1, accessorAddress } } = step;
8
+ var connectionInstance = integration_base_1.ConnectionManager.getConnectionInstanceByName(domain, connection);
9
+ if (!connectionInstance) {
10
+ debug(`no connection : ${connection}`);
11
+ throw new Error(`no connection : ${connection}`);
12
+ }
13
+ address = accessorAddress ? (0, utils_1.access)(accessorAddress, data) : address;
14
+ if (isNaN(address)) {
15
+ debug(`invalid number address : ${address}`);
16
+ throw new Error(`invalid number address : ${address}`);
17
+ }
18
+ var { readModBus } = connectionInstance;
19
+ var content = await readModBus(objectType, address, quantity, { logger });
20
+ debug(`result : ${JSON.stringify(content)}`);
21
+ return content;
22
+ }
23
+ modbusRead.parameterSpec = [
24
+ {
25
+ type: 'select',
26
+ name: 'objectType',
27
+ label: 'object-type',
28
+ property: {
29
+ options: ['', 'coil', 'descrete input', 'input register', 'holding register']
30
+ }
31
+ },
32
+ {
33
+ type: 'number',
34
+ name: 'address',
35
+ label: 'address'
36
+ },
37
+ {
38
+ type: 'number',
39
+ name: 'quantity',
40
+ label: 'quantity'
41
+ },
42
+ {
43
+ type: 'scenario-step-input',
44
+ name: 'accessorAddress',
45
+ label: 'accessor-address'
46
+ }
47
+ ];
48
+ modbusRead.help = 'integration/task/modbus-read';
49
+ integration_base_1.TaskRegistry.registerTaskHandler('modbus-read', modbusRead);
50
+ //# sourceMappingURL=modbus-read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modbus-read.js","sourceRoot":"","sources":["../../../server/engine/task/modbus-read.ts"],"names":[],"mappings":";;AAAA,iDAA8C;AAC9C,uEAAkF;AAElF,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,4BAA4B,CAAC,CAAA;AAE5D,KAAK,UAAU,UAAU,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE;IACtD,IAAI,EACF,UAAU,EACV,MAAM,EAAE,EAAE,UAAU,GAAG,MAAM,EAAE,OAAO,EAAE,QAAQ,GAAG,CAAC,EAAE,eAAe,EAAE,EACxE,GAAG,IAAI,CAAA;IAER,IAAI,kBAAkB,GAAG,oCAAiB,CAAC,2BAA2B,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAC1F,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,KAAK,CAAC,mBAAmB,UAAU,EAAE,CAAC,CAAA;QACtC,MAAM,IAAI,KAAK,CAAC,mBAAmB,UAAU,EAAE,CAAC,CAAA;IAClD,CAAC;IAED,OAAO,GAAG,eAAe,CAAC,CAAC,CAAC,IAAA,cAAM,EAAC,eAAe,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;IACnE,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACnB,KAAK,CAAC,4BAA4B,OAAO,EAAE,CAAC,CAAA;QAC5C,MAAM,IAAI,KAAK,CAAC,4BAA4B,OAAO,EAAE,CAAC,CAAA;IACxD,CAAC;IAED,IAAI,EAAE,UAAU,EAAE,GAAG,kBAAkB,CAAA;IACvC,IAAI,OAAO,GAAG,MAAM,UAAU,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;IACzE,KAAK,CAAC,YAAY,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAC5C,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,UAAU,CAAC,aAAa,GAAG;IACzB;QACE,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,aAAa;QACpB,QAAQ,EAAE;YACR,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,kBAAkB,CAAC;SAC9E;KACF;IACD;QACE,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;KACjB;IACD;QACE,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,UAAU;KAClB;IACD;QACE,IAAI,EAAE,qBAAqB;QAC3B,IAAI,EAAE,iBAAiB;QACvB,KAAK,EAAE,kBAAkB;KAC1B;CACF,CAAA;AAED,UAAU,CAAC,IAAI,GAAG,8BAA8B,CAAA;AAEhD,+BAAY,CAAC,mBAAmB,CAAC,aAAa,EAAE,UAAU,CAAC,CAAA","sourcesContent":["import { access } from '@things-factory/utils'\nimport { ConnectionManager, TaskRegistry } from '@things-factory/integration-base'\n\nconst debug = require('debug')('things-factory:modbus-read')\n\nasync function modbusRead(step, { logger, domain, data }) {\n var {\n connection,\n params: { objectType = 'coil', address, quantity = 1, accessorAddress }\n } = step\n\n var connectionInstance = ConnectionManager.getConnectionInstanceByName(domain, connection)\n if (!connectionInstance) {\n debug(`no connection : ${connection}`)\n throw new Error(`no connection : ${connection}`)\n }\n\n address = accessorAddress ? access(accessorAddress, data) : address\n if (isNaN(address)) {\n debug(`invalid number address : ${address}`)\n throw new Error(`invalid number address : ${address}`)\n }\n\n var { readModBus } = connectionInstance\n var content = await readModBus(objectType, address, quantity, { logger })\n debug(`result : ${JSON.stringify(content)}`)\n return content\n}\n\nmodbusRead.parameterSpec = [\n {\n type: 'select',\n name: 'objectType',\n label: 'object-type',\n property: {\n options: ['', 'coil', 'descrete input', 'input register', 'holding register']\n }\n },\n {\n type: 'number',\n name: 'address',\n label: 'address'\n },\n {\n type: 'number',\n name: 'quantity',\n label: 'quantity'\n },\n {\n type: 'scenario-step-input',\n name: 'accessorAddress',\n label: 'accessor-address'\n }\n]\n\nmodbusRead.help = 'integration/task/modbus-read'\n\nTaskRegistry.registerTaskHandler('modbus-read', modbusRead)\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const utils_1 = require("@things-factory/utils");
4
+ const integration_base_1 = require("@things-factory/integration-base");
5
+ const debug = require('debug')('things-factory:modbus-write-single');
6
+ async function modbusWriteSingle(step, { logger, domain, data }) {
7
+ var { connection, params: { objectType = 'coil', accessorAddress, address, accessor, value } } = step;
8
+ var connectionInstance = integration_base_1.ConnectionManager.getConnectionInstanceByName(domain, connection);
9
+ if (!connectionInstance) {
10
+ debug(`no connection : ${connection}`);
11
+ throw new Error(`no connection : ${connection}`);
12
+ }
13
+ address = accessorAddress ? (0, utils_1.access)(accessorAddress, data) : address;
14
+ if (isNaN(address)) {
15
+ debug(`invalid number address : ${address}`);
16
+ throw new Error(`invalid number address : ${address}`);
17
+ }
18
+ // determine accessor or value as a input value value
19
+ value = accessor ? (0, utils_1.access)(accessor, data) : value;
20
+ if (isNaN(value)) {
21
+ throw new Error(`invalid number value : ${value}`);
22
+ }
23
+ var { writeSingleModBus } = connectionInstance;
24
+ var content = await writeSingleModBus(objectType, address, value, { logger });
25
+ return content;
26
+ }
27
+ modbusWriteSingle.parameterSpec = [
28
+ {
29
+ type: 'select',
30
+ name: 'objectType',
31
+ label: 'object-type',
32
+ property: {
33
+ options: ['', 'coil', 'holding register']
34
+ }
35
+ },
36
+ {
37
+ type: 'number',
38
+ name: 'address',
39
+ label: 'address'
40
+ },
41
+ {
42
+ type: 'number',
43
+ name: 'value',
44
+ label: 'value'
45
+ },
46
+ {
47
+ type: 'scenario-step-input',
48
+ name: 'accessor',
49
+ label: 'accessor-value'
50
+ },
51
+ {
52
+ type: 'scenario-step-input',
53
+ name: 'accessorAddress',
54
+ label: 'accessor-address'
55
+ }
56
+ ];
57
+ modbusWriteSingle.help = 'integration/task/modbus-write-single';
58
+ integration_base_1.TaskRegistry.registerTaskHandler('modbus-write-single', modbusWriteSingle);
59
+ //# sourceMappingURL=modbus-write-single.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modbus-write-single.js","sourceRoot":"","sources":["../../../server/engine/task/modbus-write-single.ts"],"names":[],"mappings":";;AAAA,iDAA8C;AAC9C,uEAAkF;AAElF,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,oCAAoC,CAAC,CAAA;AAEpE,KAAK,UAAU,iBAAiB,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE;IAC7D,IAAI,EACF,UAAU,EACV,MAAM,EAAE,EAAE,UAAU,GAAG,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,EAC3E,GAAG,IAAI,CAAA;IAER,IAAI,kBAAkB,GAAG,oCAAiB,CAAC,2BAA2B,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAC1F,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,KAAK,CAAC,mBAAmB,UAAU,EAAE,CAAC,CAAA;QACtC,MAAM,IAAI,KAAK,CAAC,mBAAmB,UAAU,EAAE,CAAC,CAAA;IAClD,CAAC;IAED,OAAO,GAAG,eAAe,CAAC,CAAC,CAAC,IAAA,cAAM,EAAC,eAAe,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;IACnE,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACnB,KAAK,CAAC,4BAA4B,OAAO,EAAE,CAAC,CAAA;QAC5C,MAAM,IAAI,KAAK,CAAC,4BAA4B,OAAO,EAAE,CAAC,CAAA;IACxD,CAAC;IAED,qDAAqD;IACrD,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAA,cAAM,EAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IACjD,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAA;IACpD,CAAC;IAED,IAAI,EAAE,iBAAiB,EAAE,GAAG,kBAAkB,CAAA;IAC9C,IAAI,OAAO,GAAG,MAAM,iBAAiB,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;IAC7E,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,iBAAiB,CAAC,aAAa,GAAG;IAChC;QACE,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,aAAa;QACpB,QAAQ,EAAE;YACR,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,kBAAkB,CAAC;SAC1C;KACF;IACD;QACE,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;KACjB;IACD;QACE,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,OAAO;KACf;IACD;QACE,IAAI,EAAE,qBAAqB;QAC3B,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,gBAAgB;KACxB;IACD;QACE,IAAI,EAAE,qBAAqB;QAC3B,IAAI,EAAE,iBAAiB;QACvB,KAAK,EAAE,kBAAkB;KAC1B;CACF,CAAA;AAED,iBAAiB,CAAC,IAAI,GAAG,sCAAsC,CAAA;AAE/D,+BAAY,CAAC,mBAAmB,CAAC,qBAAqB,EAAE,iBAAiB,CAAC,CAAA","sourcesContent":["import { access } from '@things-factory/utils'\nimport { ConnectionManager, TaskRegistry } from '@things-factory/integration-base'\n\nconst debug = require('debug')('things-factory:modbus-write-single')\n\nasync function modbusWriteSingle(step, { logger, domain, data }) {\n var {\n connection,\n params: { objectType = 'coil', accessorAddress, address, accessor, value }\n } = step\n\n var connectionInstance = ConnectionManager.getConnectionInstanceByName(domain, connection)\n if (!connectionInstance) {\n debug(`no connection : ${connection}`)\n throw new Error(`no connection : ${connection}`)\n }\n\n address = accessorAddress ? access(accessorAddress, data) : address\n if (isNaN(address)) {\n debug(`invalid number address : ${address}`)\n throw new Error(`invalid number address : ${address}`)\n }\n\n // determine accessor or value as a input value value\n value = accessor ? access(accessor, data) : value\n if (isNaN(value)) {\n throw new Error(`invalid number value : ${value}`)\n }\n\n var { writeSingleModBus } = connectionInstance\n var content = await writeSingleModBus(objectType, address, value, { logger })\n return content\n}\n\nmodbusWriteSingle.parameterSpec = [\n {\n type: 'select',\n name: 'objectType',\n label: 'object-type',\n property: {\n options: ['', 'coil', 'holding register']\n }\n },\n {\n type: 'number',\n name: 'address',\n label: 'address'\n },\n {\n type: 'number',\n name: 'value',\n label: 'value'\n },\n {\n type: 'scenario-step-input',\n name: 'accessor',\n label: 'accessor-value'\n },\n {\n type: 'scenario-step-input',\n name: 'accessorAddress',\n label: 'accessor-address'\n }\n]\n\nmodbusWriteSingle.help = 'integration/task/modbus-write-single'\n\nTaskRegistry.registerTaskHandler('modbus-write-single', modbusWriteSingle)\n"]}
@@ -0,0 +1 @@
1
+ import './engine';
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("./engine");
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../server/index.ts"],"names":[],"mappings":";;AAAA,oBAAiB","sourcesContent":["import './engine'\n"]}