@things-factory/integration-melsec 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.
Files changed (32) hide show
  1. package/dist-server/engine/connector/index.d.ts +1 -0
  2. package/dist-server/engine/connector/index.js +4 -0
  3. package/dist-server/engine/connector/index.js.map +1 -0
  4. package/dist-server/engine/connector/melsec-plc.d.ts +17 -0
  5. package/dist-server/engine/connector/melsec-plc.js +183 -0
  6. package/dist-server/engine/connector/melsec-plc.js.map +1 -0
  7. package/dist-server/engine/index.d.ts +2 -0
  8. package/dist-server/engine/index.js +5 -0
  9. package/dist-server/engine/index.js.map +1 -0
  10. package/dist-server/engine/task/index.d.ts +5 -0
  11. package/dist-server/engine/task/index.js +8 -0
  12. package/dist-server/engine/task/index.js.map +1 -0
  13. package/dist-server/engine/task/melsec-read-coil.d.ts +1 -0
  14. package/dist-server/engine/task/melsec-read-coil.js +51 -0
  15. package/dist-server/engine/task/melsec-read-coil.js.map +1 -0
  16. package/dist-server/engine/task/melsec-read-word.d.ts +1 -0
  17. package/dist-server/engine/task/melsec-read-word.js +48 -0
  18. package/dist-server/engine/task/melsec-read-word.js.map +1 -0
  19. package/dist-server/engine/task/melsec-wait-coil.d.ts +1 -0
  20. package/dist-server/engine/task/melsec-wait-coil.js +72 -0
  21. package/dist-server/engine/task/melsec-wait-coil.js.map +1 -0
  22. package/dist-server/engine/task/melsec-write-coil.d.ts +1 -0
  23. package/dist-server/engine/task/melsec-write-coil.js +85 -0
  24. package/dist-server/engine/task/melsec-write-coil.js.map +1 -0
  25. package/dist-server/engine/task/melsec-write-word.d.ts +1 -0
  26. package/dist-server/engine/task/melsec-write-word.js +69 -0
  27. package/dist-server/engine/task/melsec-write-word.js.map +1 -0
  28. package/dist-server/index.d.ts +1 -0
  29. package/dist-server/index.js +4 -0
  30. package/dist-server/index.js.map +1 -0
  31. package/dist-server/tsconfig.tsbuildinfo +1 -0
  32. package/package.json +3 -3
@@ -0,0 +1 @@
1
+ import './melsec-plc';
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("./melsec-plc");
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/engine/connector/index.ts"],"names":[],"mappings":";;AAAA,wBAAqB","sourcesContent":["import './melsec-plc'\n"]}
@@ -0,0 +1,17 @@
1
+ import { Connector, Connection } from '@things-factory/integration-base';
2
+ export declare class MelsecPLCConnector implements Connector {
3
+ static getWriteCoilCommand(deviceCode: any, writeStartDevice: any, writeCoilValue: any, writeLength: any): string;
4
+ static getWriteWordCommand(deviceCode: any, writeStartDevice: any, writeWordValue: any): string;
5
+ static getReadCoilCommand(deviceCode: any, readStartDevice: any, readLength: any): string;
6
+ static getReadWordCommand(deviceCode: any, readStartDevice: any): string;
7
+ ready(connectionConfigs: any): Promise<void>;
8
+ connect(config: any): Promise<void>;
9
+ disconnect(connection: Connection): Promise<void>;
10
+ get parameterSpec(): {
11
+ type: string;
12
+ name: string;
13
+ label: string;
14
+ }[];
15
+ get taskPrefixes(): string[];
16
+ get help(): string;
17
+ }
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MelsecPLCConnector = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const net_1 = tslib_1.__importDefault(require("net"));
6
+ const promise_socket_1 = tslib_1.__importDefault(require("promise-socket"));
7
+ const p_queue_1 = tslib_1.__importDefault(require("p-queue"));
8
+ const utils_1 = require("@things-factory/utils");
9
+ const integration_base_1 = require("@things-factory/integration-base");
10
+ const subHeader = '5000';
11
+ const networkNumber = '00';
12
+ const requireNumber = 'FF';
13
+ const requireIoNumber = '03FF';
14
+ const requireMultiNumber = '00';
15
+ const readrequireLength = '0018';
16
+ const writerequireLength = '0019';
17
+ const writewordrequireLength = '001C';
18
+ const reserve = '0000';
19
+ const readCommand = '0401';
20
+ const readWordSubCommand = '0000';
21
+ const readCoilSubCommand = '0001';
22
+ const writeCommand = '1401';
23
+ const writeWordSubCommand = '0000';
24
+ const writeSubCommand = '0001';
25
+ const readLengthDevice = '0001';
26
+ const writeLengthDevice = '0001';
27
+ class MelsecPLCConnector {
28
+ static getWriteCoilCommand(deviceCode, writeStartDevice, writeCoilValue, writeLength) {
29
+ if (writeLength) {
30
+ writeLength = writeLength.toString().padStart(4, '0');
31
+ }
32
+ return (subHeader +
33
+ networkNumber +
34
+ requireNumber +
35
+ requireIoNumber +
36
+ requireMultiNumber +
37
+ writerequireLength +
38
+ reserve +
39
+ writeCommand +
40
+ writeSubCommand +
41
+ deviceCode +
42
+ writeStartDevice +
43
+ (writeLength || writeLengthDevice) +
44
+ writeCoilValue);
45
+ }
46
+ static getWriteWordCommand(deviceCode, writeStartDevice, writeWordValue) {
47
+ return (subHeader +
48
+ networkNumber +
49
+ requireNumber +
50
+ requireIoNumber +
51
+ requireMultiNumber +
52
+ writewordrequireLength +
53
+ reserve +
54
+ writeCommand +
55
+ writeWordSubCommand +
56
+ deviceCode +
57
+ writeStartDevice +
58
+ writeLengthDevice +
59
+ writeWordValue);
60
+ }
61
+ static getReadCoilCommand(deviceCode, readStartDevice, readLength) {
62
+ if (readLength) {
63
+ readLength = readLength.toString().padStart(4, '0');
64
+ }
65
+ return (subHeader +
66
+ networkNumber +
67
+ requireNumber +
68
+ requireIoNumber +
69
+ requireMultiNumber +
70
+ readrequireLength +
71
+ reserve +
72
+ readCommand +
73
+ readCoilSubCommand +
74
+ deviceCode +
75
+ readStartDevice +
76
+ (readLength || readLengthDevice));
77
+ }
78
+ static getReadWordCommand(deviceCode, readStartDevice) {
79
+ return (subHeader +
80
+ networkNumber +
81
+ requireNumber +
82
+ requireIoNumber +
83
+ requireMultiNumber +
84
+ readrequireLength +
85
+ reserve +
86
+ readCommand +
87
+ readWordSubCommand +
88
+ deviceCode +
89
+ readStartDevice +
90
+ readLengthDevice);
91
+ }
92
+ async ready(connectionConfigs) {
93
+ await Promise.all(connectionConfigs.map(this.connect));
94
+ integration_base_1.ConnectionManager.logger.info('mitsubishi-plc connections are ready');
95
+ }
96
+ async connect(config) {
97
+ if (integration_base_1.ConnectionManager.getConnectionInstance(config)) {
98
+ return;
99
+ }
100
+ var [host, port = 1025] = config.endpoint.split(':');
101
+ var socket = new promise_socket_1.default(new net_1.default.Socket());
102
+ await socket.connect(port, host);
103
+ var queue = new p_queue_1.default({ concurrency: 1 });
104
+ var keepalive = true;
105
+ integration_base_1.ConnectionManager.addConnectionInstance(config, {
106
+ request: async function (message, length, { logger }) {
107
+ return await queue.add(async () => {
108
+ while (keepalive) {
109
+ try {
110
+ /* send request message */
111
+ await socket.write(message);
112
+ logger && logger.info(`Request : ${message}`);
113
+ var responseCompleted = '';
114
+ if (length > 0) {
115
+ while (length - responseCompleted.length > 0) {
116
+ logger && logger.info(`Will read ${length - responseCompleted.length}`);
117
+ let response = await socket.read(); // length - responseCompleted.length)
118
+ if (!response) {
119
+ // socket ended or closed
120
+ throw new Error('socket closed');
121
+ }
122
+ responseCompleted += response.toString();
123
+ }
124
+ }
125
+ else {
126
+ let response = await socket.read();
127
+ if (!response) {
128
+ // socket ended or closed
129
+ throw new Error('socket closed');
130
+ }
131
+ responseCompleted = response.toString();
132
+ }
133
+ logger && logger.info(`Response : ${responseCompleted}`);
134
+ return responseCompleted;
135
+ }
136
+ catch (e) {
137
+ logger.error('plc command(write-read) failed.', e);
138
+ if (keepalive) {
139
+ socket && socket.destroy();
140
+ socket = new promise_socket_1.default(new net_1.default.Socket());
141
+ await socket.connect(port, host);
142
+ await (0, utils_1.sleep)(1000);
143
+ }
144
+ else {
145
+ throw e;
146
+ }
147
+ }
148
+ }
149
+ throw new Error(`${config.name} maybe disconnected normally`);
150
+ });
151
+ },
152
+ close: function () {
153
+ queue.clear();
154
+ keepalive = false;
155
+ socket.destroy();
156
+ }
157
+ });
158
+ integration_base_1.ConnectionManager.logger.info(`mitsubishi-plc connection(${config.name}:${config.endpoint}) is connected`);
159
+ }
160
+ async disconnect(connection) {
161
+ var { close } = integration_base_1.ConnectionManager.removeConnectionInstance(connection);
162
+ close();
163
+ integration_base_1.ConnectionManager.logger.info(`mitsubishi-plc connection(${connection.name}) is disconnected`);
164
+ }
165
+ get parameterSpec() {
166
+ return [
167
+ {
168
+ type: 'checkbox',
169
+ name: 'keepalive',
170
+ label: 'keepalive'
171
+ }
172
+ ];
173
+ }
174
+ get taskPrefixes() {
175
+ return ['melsec'];
176
+ }
177
+ get help() {
178
+ return 'integration/connector/melsec-plc';
179
+ }
180
+ }
181
+ exports.MelsecPLCConnector = MelsecPLCConnector;
182
+ integration_base_1.ConnectionManager.registerConnector('melsec-plc', new MelsecPLCConnector());
183
+ //# sourceMappingURL=melsec-plc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"melsec-plc.js","sourceRoot":"","sources":["../../../server/engine/connector/melsec-plc.ts"],"names":[],"mappings":"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","sourcesContent":["import net from 'net'\nimport PromiseSocket from 'promise-socket'\nimport PQueue from 'p-queue'\nimport { sleep } from '@things-factory/utils'\n\nimport { ConnectionManager, Connector, Connection } from '@things-factory/integration-base'\n\nconst subHeader = '5000'\nconst networkNumber = '00'\nconst requireNumber = 'FF'\nconst requireIoNumber = '03FF'\nconst requireMultiNumber = '00'\nconst readrequireLength = '0018'\nconst writerequireLength = '0019'\nconst writewordrequireLength = '001C'\nconst reserve = '0000'\nconst readCommand = '0401'\nconst readWordSubCommand = '0000'\nconst readCoilSubCommand = '0001'\nconst writeCommand = '1401'\nconst writeWordSubCommand = '0000'\nconst writeSubCommand = '0001'\nconst readLengthDevice = '0001'\nconst writeLengthDevice = '0001'\n\nexport class MelsecPLCConnector implements Connector {\n static getWriteCoilCommand(deviceCode, writeStartDevice, writeCoilValue, writeLength) {\n if (writeLength) {\n writeLength = writeLength.toString().padStart(4, '0')\n }\n\n return (\n subHeader +\n networkNumber +\n requireNumber +\n requireIoNumber +\n requireMultiNumber +\n writerequireLength +\n reserve +\n writeCommand +\n writeSubCommand +\n deviceCode +\n writeStartDevice +\n (writeLength || writeLengthDevice) +\n writeCoilValue\n )\n }\n\n static getWriteWordCommand(deviceCode, writeStartDevice, writeWordValue) {\n return (\n subHeader +\n networkNumber +\n requireNumber +\n requireIoNumber +\n requireMultiNumber +\n writewordrequireLength +\n reserve +\n writeCommand +\n writeWordSubCommand +\n deviceCode +\n writeStartDevice +\n writeLengthDevice +\n writeWordValue\n )\n }\n\n static getReadCoilCommand(deviceCode, readStartDevice, readLength) {\n if (readLength) {\n readLength = readLength.toString().padStart(4, '0')\n }\n\n return (\n subHeader +\n networkNumber +\n requireNumber +\n requireIoNumber +\n requireMultiNumber +\n readrequireLength +\n reserve +\n readCommand +\n readCoilSubCommand +\n deviceCode +\n readStartDevice +\n (readLength || readLengthDevice)\n )\n }\n\n static getReadWordCommand(deviceCode, readStartDevice) {\n return (\n subHeader +\n networkNumber +\n requireNumber +\n requireIoNumber +\n requireMultiNumber +\n readrequireLength +\n reserve +\n readCommand +\n readWordSubCommand +\n deviceCode +\n readStartDevice +\n readLengthDevice\n )\n }\n\n async ready(connectionConfigs) {\n await Promise.all(connectionConfigs.map(this.connect))\n\n ConnectionManager.logger.info('mitsubishi-plc connections are ready')\n }\n\n async connect(config) {\n if (ConnectionManager.getConnectionInstance(config)) {\n return\n }\n\n var [host, port = 1025] = config.endpoint.split(':')\n\n var socket = new PromiseSocket(new net.Socket())\n\n await socket.connect(port, host)\n\n var queue = new PQueue({ concurrency: 1 })\n var keepalive = true\n\n ConnectionManager.addConnectionInstance(config, {\n request: async function (message, length, { logger }) {\n return await queue.add(async () => {\n while (keepalive) {\n try {\n /* send request message */\n await socket.write(message)\n logger && logger.info(`Request : ${message}`)\n var responseCompleted = ''\n\n if (length > 0) {\n while (length - responseCompleted.length > 0) {\n logger && logger.info(`Will read ${length - responseCompleted.length}`)\n let response = await socket.read() // length - responseCompleted.length)\n if (!response) {\n // socket ended or closed\n throw new Error('socket closed')\n }\n responseCompleted += response.toString()\n }\n } else {\n let response = await socket.read()\n if (!response) {\n // socket ended or closed\n throw new Error('socket closed')\n }\n responseCompleted = response.toString()\n }\n\n logger && logger.info(`Response : ${responseCompleted}`)\n return responseCompleted\n } catch (e) {\n logger.error('plc command(write-read) failed.', e)\n\n if (keepalive) {\n socket && socket.destroy()\n\n socket = new PromiseSocket(new net.Socket())\n await socket.connect(port, host)\n\n await sleep(1000)\n } else {\n throw e\n }\n }\n }\n\n throw new Error(`${config.name} maybe disconnected normally`)\n })\n },\n close: function () {\n queue.clear()\n keepalive = false\n socket.destroy()\n }\n })\n\n ConnectionManager.logger.info(`mitsubishi-plc connection(${config.name}:${config.endpoint}) is connected`)\n }\n\n async disconnect(connection: Connection) {\n var { close } = ConnectionManager.removeConnectionInstance(connection)\n close()\n\n ConnectionManager.logger.info(`mitsubishi-plc connection(${connection.name}) is disconnected`)\n }\n\n get parameterSpec() {\n return [\n {\n type: 'checkbox',\n name: 'keepalive',\n label: 'keepalive'\n }\n ]\n }\n\n get taskPrefixes() {\n return ['melsec']\n }\n\n get help() {\n return 'integration/connector/melsec-plc'\n }\n}\n\nConnectionManager.registerConnector('melsec-plc', new MelsecPLCConnector())\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,5 @@
1
+ import './melsec-read-coil';
2
+ import './melsec-wait-coil';
3
+ import './melsec-write-coil';
4
+ import './melsec-read-word';
5
+ import './melsec-write-word';
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("./melsec-read-coil");
4
+ require("./melsec-wait-coil");
5
+ require("./melsec-write-coil");
6
+ require("./melsec-read-word");
7
+ require("./melsec-write-word");
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/engine/task/index.ts"],"names":[],"mappings":";;AAAA,8BAA2B;AAC3B,8BAA2B;AAC3B,+BAA4B;AAC5B,8BAA2B;AAC3B,+BAA4B","sourcesContent":["import './melsec-read-coil'\nimport './melsec-wait-coil'\nimport './melsec-write-coil'\nimport './melsec-read-word'\nimport './melsec-write-word'\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const integration_base_1 = require("@things-factory/integration-base");
4
+ const melsec_plc_1 = require("../connector/melsec-plc");
5
+ async function MelsecReadCoil(step, { logger, domain }) {
6
+ var { connection: connectionName, params: { plcAddress: address, readLength: readLength } } = step;
7
+ var connection = integration_base_1.ConnectionManager.getConnectionInstanceByName(domain, connectionName);
8
+ if (!connection) {
9
+ throw new Error(`connection '${connectionName}' is not established.`);
10
+ }
11
+ var { request } = connection;
12
+ var deviceCode = address.substring(0, 1) + '*';
13
+ var af_address = Number(address.substring(1)).toString();
14
+ var len = af_address.length;
15
+ for (var i = 0; i < 6 - len; i++) {
16
+ af_address = '0' + af_address;
17
+ }
18
+ var readStartDevice = af_address;
19
+ var sendMessage = melsec_plc_1.MelsecPLCConnector.getReadCoilCommand(deviceCode, readStartDevice, readLength);
20
+ // Request : 500000FF03FF000018000004010001M*0001000001
21
+ // Response : D00000FF03FF00000500000
22
+ var content = await request(sendMessage, 23, { logger }); // (22 + readLength)에서 현재 readLength는 1로 고정
23
+ // TODO readLength가 1이 아닐때 데이터 처리.
24
+ if (content.substring(17, 18) == '5') {
25
+ var data = content.substring(22, 23);
26
+ logger.info(content);
27
+ logger.info(`received response is ok. received: ${data}`);
28
+ return {
29
+ data
30
+ };
31
+ }
32
+ else {
33
+ // error
34
+ throw new Error('response not applicable');
35
+ }
36
+ }
37
+ MelsecReadCoil.parameterSpec = [
38
+ {
39
+ type: 'string',
40
+ name: 'plcAddress',
41
+ label: 'plc_address'
42
+ },
43
+ {
44
+ type: 'number',
45
+ name: 'readLength',
46
+ label: 'read_length'
47
+ }
48
+ ];
49
+ MelsecReadCoil.help = 'integration/task/melsec-read-coil';
50
+ integration_base_1.TaskRegistry.registerTaskHandler('melsec-read-coil', MelsecReadCoil);
51
+ //# sourceMappingURL=melsec-read-coil.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"melsec-read-coil.js","sourceRoot":"","sources":["../../../server/engine/task/melsec-read-coil.ts"],"names":[],"mappings":";;AAAA,uEAAkF;AAClF,wDAA4D;AAE5D,KAAK,UAAU,cAAc,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;IACpD,IAAI,EACF,UAAU,EAAE,cAAc,EAC1B,MAAM,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,EACxD,GAAG,IAAI,CAAA;IAER,IAAI,UAAU,GAAG,oCAAiB,CAAC,2BAA2B,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;IACtF,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,eAAe,cAAc,uBAAuB,CAAC,CAAA;IACvE,CAAC;IAED,IAAI,EAAE,OAAO,EAAE,GAAG,UAAU,CAAA;IAE5B,IAAI,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAA;IAC9C,IAAI,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACxD,IAAI,GAAG,GAAG,UAAU,CAAC,MAAM,CAAA;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,UAAU,GAAG,GAAG,GAAG,UAAU,CAAA;IAC/B,CAAC;IACD,IAAI,eAAe,GAAG,UAAU,CAAA;IAChC,IAAI,WAAW,GAAG,+BAAkB,CAAC,kBAAkB,CAAC,UAAU,EAAE,eAAe,EAAE,UAAU,CAAC,CAAA;IAEhG,uDAAuD;IACvD,qCAAqC;IACrC,IAAI,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA,CAAC,2CAA2C;IAEpG,kCAAkC;IAClC,IAAI,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC;QACrC,IAAI,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;QAEpC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACpB,MAAM,CAAC,IAAI,CAAC,sCAAsC,IAAI,EAAE,CAAC,CAAA;QAEzD,OAAO;YACL,IAAI;SACL,CAAA;IACH,CAAC;SAAM,CAAC;QACN,QAAQ;QACR,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAA;IAC5C,CAAC;AACH,CAAC;AAED,cAAc,CAAC,aAAa,GAAG;IAC7B;QACE,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,aAAa;KACrB;IACD;QACE,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,aAAa;KACrB;CACF,CAAA;AAED,cAAc,CAAC,IAAI,GAAG,mCAAmC,CAAA;AAEzD,+BAAY,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAA","sourcesContent":["import { ConnectionManager, TaskRegistry } from '@things-factory/integration-base'\nimport { MelsecPLCConnector } from '../connector/melsec-plc'\n\nasync function MelsecReadCoil(step, { logger, domain }) {\n var {\n connection: connectionName,\n params: { plcAddress: address, readLength: readLength }\n } = step\n\n var connection = ConnectionManager.getConnectionInstanceByName(domain, connectionName)\n if (!connection) {\n throw new Error(`connection '${connectionName}' is not established.`)\n }\n\n var { request } = connection\n\n var deviceCode = address.substring(0, 1) + '*'\n var af_address = Number(address.substring(1)).toString()\n var len = af_address.length\n for (var i = 0; i < 6 - len; i++) {\n af_address = '0' + af_address\n }\n var readStartDevice = af_address\n var sendMessage = MelsecPLCConnector.getReadCoilCommand(deviceCode, readStartDevice, readLength)\n\n // Request : 500000FF03FF000018000004010001M*0001000001\n // Response : D00000FF03FF00000500000\n var content = await request(sendMessage, 23, { logger }) // (22 + readLength)에서 현재 readLength는 1로 고정\n\n // TODO readLength가 1이 아닐때 데이터 처리.\n if (content.substring(17, 18) == '5') {\n var data = content.substring(22, 23)\n\n logger.info(content)\n logger.info(`received response is ok. received: ${data}`)\n\n return {\n data\n }\n } else {\n // error\n throw new Error('response not applicable')\n }\n}\n\nMelsecReadCoil.parameterSpec = [\n {\n type: 'string',\n name: 'plcAddress',\n label: 'plc_address'\n },\n {\n type: 'number',\n name: 'readLength',\n label: 'read_length'\n }\n]\n\nMelsecReadCoil.help = 'integration/task/melsec-read-coil'\n\nTaskRegistry.registerTaskHandler('melsec-read-coil', MelsecReadCoil)\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const integration_base_1 = require("@things-factory/integration-base");
4
+ const melsec_plc_1 = require("../connector/melsec-plc");
5
+ async function MelsecReadWord(step, { logger, domain }) {
6
+ var { connection: connectionName, params: { plcAddress: address, signed = false } } = step;
7
+ var connection = integration_base_1.ConnectionManager.getConnectionInstanceByName(domain, connectionName);
8
+ if (!connection) {
9
+ throw new Error(`connection '${connectionName}' is not established.`);
10
+ }
11
+ var { request } = connection;
12
+ var deviceCode = address.substring(0, 1) + '*';
13
+ var af_address = Number(address.substring(1)).toString();
14
+ var len = af_address.length;
15
+ for (var i = 0; i < 6 - len; i++) {
16
+ af_address = '0' + af_address;
17
+ }
18
+ var readStartDevice = af_address;
19
+ var sendMessage = melsec_plc_1.MelsecPLCConnector.getReadWordCommand(deviceCode, readStartDevice);
20
+ // Request : 500000FF03FF000018000004010000D*0001010001
21
+ // Response : D00000FF03FF000008000003E9
22
+ var content = await request(sendMessage, 26, { logger });
23
+ var wordValue = content.substring(22, 26);
24
+ var data = parseInt(wordValue, 16);
25
+ if (signed && (data & 0x8000) > 0) {
26
+ data -= 0x10000;
27
+ }
28
+ logger.info(content);
29
+ logger.info(`received response is ok. received: ${data}`);
30
+ return {
31
+ data
32
+ };
33
+ }
34
+ MelsecReadWord.parameterSpec = [
35
+ {
36
+ type: 'string',
37
+ name: 'plcAddress',
38
+ label: 'plc_address'
39
+ },
40
+ {
41
+ type: 'checkbox',
42
+ name: 'signed',
43
+ label: 'signed'
44
+ }
45
+ ];
46
+ MelsecReadWord.help = 'integration/task/melsec-read-word';
47
+ integration_base_1.TaskRegistry.registerTaskHandler('melsec-read-word', MelsecReadWord);
48
+ //# sourceMappingURL=melsec-read-word.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"melsec-read-word.js","sourceRoot":"","sources":["../../../server/engine/task/melsec-read-word.ts"],"names":[],"mappings":";;AAAA,uEAAkF;AAClF,wDAA4D;AAE5D,KAAK,UAAU,cAAc,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;IACpD,IAAI,EACF,UAAU,EAAE,cAAc,EAC1B,MAAM,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,EAChD,GAAG,IAAI,CAAA;IAER,IAAI,UAAU,GAAG,oCAAiB,CAAC,2BAA2B,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;IACtF,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,eAAe,cAAc,uBAAuB,CAAC,CAAA;IACvE,CAAC;IAED,IAAI,EAAE,OAAO,EAAE,GAAG,UAAU,CAAA;IAE5B,IAAI,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAA;IAC9C,IAAI,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACxD,IAAI,GAAG,GAAG,UAAU,CAAC,MAAM,CAAA;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,UAAU,GAAG,GAAG,GAAG,UAAU,CAAA;IAC/B,CAAC;IACD,IAAI,eAAe,GAAG,UAAU,CAAA;IAChC,IAAI,WAAW,GAAG,+BAAkB,CAAC,kBAAkB,CAAC,UAAU,EAAE,eAAe,CAAC,CAAA;IAEpF,uDAAuD;IACvD,wCAAwC;IACxC,IAAI,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;IAExD,IAAI,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IACzC,IAAI,IAAI,GAAG,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;IAElC,IAAI,MAAM,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,IAAI,IAAI,OAAO,CAAA;IACjB,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACpB,MAAM,CAAC,IAAI,CAAC,sCAAsC,IAAI,EAAE,CAAC,CAAA;IAEzD,OAAO;QACL,IAAI;KACL,CAAA;AACH,CAAC;AAED,cAAc,CAAC,aAAa,GAAG;IAC7B;QACE,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,aAAa;KACrB;IACD;QACE,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,QAAQ;KAChB;CACF,CAAA;AAED,cAAc,CAAC,IAAI,GAAG,mCAAmC,CAAA;AAEzD,+BAAY,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAA","sourcesContent":["import { ConnectionManager, TaskRegistry } from '@things-factory/integration-base'\nimport { MelsecPLCConnector } from '../connector/melsec-plc'\n\nasync function MelsecReadWord(step, { logger, domain }) {\n var {\n connection: connectionName,\n params: { plcAddress: address, signed = false }\n } = step\n\n var connection = ConnectionManager.getConnectionInstanceByName(domain, connectionName)\n if (!connection) {\n throw new Error(`connection '${connectionName}' is not established.`)\n }\n\n var { request } = connection\n\n var deviceCode = address.substring(0, 1) + '*'\n var af_address = Number(address.substring(1)).toString()\n var len = af_address.length\n for (var i = 0; i < 6 - len; i++) {\n af_address = '0' + af_address\n }\n var readStartDevice = af_address\n var sendMessage = MelsecPLCConnector.getReadWordCommand(deviceCode, readStartDevice)\n\n // Request : 500000FF03FF000018000004010000D*0001010001\n // Response : D00000FF03FF000008000003E9\n var content = await request(sendMessage, 26, { logger })\n\n var wordValue = content.substring(22, 26)\n var data = parseInt(wordValue, 16)\n\n if (signed && (data & 0x8000) > 0) {\n data -= 0x10000\n }\n\n logger.info(content)\n logger.info(`received response is ok. received: ${data}`)\n\n return {\n data\n }\n}\n\nMelsecReadWord.parameterSpec = [\n {\n type: 'string',\n name: 'plcAddress',\n label: 'plc_address'\n },\n {\n type: 'checkbox',\n name: 'signed',\n label: 'signed'\n }\n]\n\nMelsecReadWord.help = 'integration/task/melsec-read-word'\n\nTaskRegistry.registerTaskHandler('melsec-read-word', MelsecReadWord)\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const integration_base_1 = require("@things-factory/integration-base");
4
+ const utils_1 = require("@things-factory/utils");
5
+ const melsec_plc_1 = require("../connector/melsec-plc");
6
+ async function MelsecWaitForCoil(step, { logger, root, domain }) {
7
+ var { connection: connectionName, params: { plcAddress: address, value, waitTerm = 50 } } = step;
8
+ var connection = integration_base_1.ConnectionManager.getConnectionInstanceByName(domain, connectionName);
9
+ if (!connection) {
10
+ throw new Error(`connection '${connectionName}' is not established.`);
11
+ }
12
+ var { request } = connection;
13
+ var deviceCode = address.substring(0, 1) + '*';
14
+ var af_address = Number(address.substring(1)).toString();
15
+ var len = af_address.length;
16
+ for (var i = 0; i < 6 - len; i++) {
17
+ af_address = '0' + af_address;
18
+ }
19
+ var readStartDevice = af_address;
20
+ var sendMessage = melsec_plc_1.MelsecPLCConnector.getReadCoilCommand(deviceCode, readStartDevice, undefined);
21
+ while (true) {
22
+ let state = root.getState();
23
+ if (state == integration_base_1.ScenarioInstanceStatus.STARTED /* STARTED */) {
24
+ var content = await request(sendMessage, 23, { logger });
25
+ if (content.substring(17, 18) == '5') {
26
+ var coilValue = content.substring(22, 23);
27
+ if (value == coilValue) {
28
+ logger.info('received response is ok. required: %s, received: %s', value, coilValue);
29
+ return {
30
+ data: coilValue
31
+ };
32
+ }
33
+ else {
34
+ logger.info('received response, but not accepted. required: %s, received: %s', value, coilValue);
35
+ await (0, utils_1.sleep)(waitTerm);
36
+ continue;
37
+ }
38
+ }
39
+ else {
40
+ // error
41
+ throw new Error('response not applicable');
42
+ }
43
+ }
44
+ else if (state == integration_base_1.ScenarioInstanceStatus.STOPPED /* PAUSED */) {
45
+ await (0, utils_1.sleep)(waitTerm);
46
+ }
47
+ else {
48
+ throw new Error('scenario stopped unexpectedly');
49
+ }
50
+ }
51
+ }
52
+ MelsecWaitForCoil.parameterSpec = [
53
+ {
54
+ type: 'string',
55
+ name: 'plcAddress',
56
+ label: 'plc_address'
57
+ },
58
+ {
59
+ type: 'string',
60
+ name: 'value',
61
+ label: 'expected_value'
62
+ },
63
+ {
64
+ type: 'number',
65
+ name: 'waitTerm',
66
+ placeholder: 'milli-seconds',
67
+ label: 'wait_term'
68
+ }
69
+ ];
70
+ MelsecWaitForCoil.help = 'integration/task/melsec-wait-coil';
71
+ integration_base_1.TaskRegistry.registerTaskHandler('melsec-wait-coil', MelsecWaitForCoil);
72
+ //# sourceMappingURL=melsec-wait-coil.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"melsec-wait-coil.js","sourceRoot":"","sources":["../../../server/engine/task/melsec-wait-coil.ts"],"names":[],"mappings":"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","sourcesContent":["import { ConnectionManager, Context, ScenarioInstanceStatus, TaskRegistry } from '@things-factory/integration-base'\nimport { sleep } from '@things-factory/utils'\n\nimport { MelsecPLCConnector } from '../connector/melsec-plc'\n\nasync function MelsecWaitForCoil(step, { logger, root, domain }: Context) {\n var {\n connection: connectionName,\n params: { plcAddress: address, value, waitTerm = 50 }\n } = step\n\n var connection = ConnectionManager.getConnectionInstanceByName(domain, connectionName)\n if (!connection) {\n throw new Error(`connection '${connectionName}' is not established.`)\n }\n\n var { request } = connection\n\n var deviceCode = address.substring(0, 1) + '*'\n var af_address = Number(address.substring(1)).toString()\n var len = af_address.length\n for (var i = 0; i < 6 - len; i++) {\n af_address = '0' + af_address\n }\n var readStartDevice = af_address\n var sendMessage = MelsecPLCConnector.getReadCoilCommand(deviceCode, readStartDevice, undefined)\n\n while (true) {\n let state = root.getState()\n if (state == ScenarioInstanceStatus.STARTED /* STARTED */) {\n var content = await request(sendMessage, 23, { logger })\n\n if (content.substring(17, 18) == '5') {\n var coilValue = content.substring(22, 23)\n\n if (value == coilValue) {\n logger.info('received response is ok. required: %s, received: %s', value, coilValue)\n\n return {\n data: coilValue\n }\n } else {\n logger.info('received response, but not accepted. required: %s, received: %s', value, coilValue)\n await sleep(waitTerm)\n continue\n }\n } else {\n // error\n throw new Error('response not applicable')\n }\n } else if (state == ScenarioInstanceStatus.STOPPED /* PAUSED */) {\n await sleep(waitTerm)\n } else {\n throw new Error('scenario stopped unexpectedly')\n }\n }\n}\n\nMelsecWaitForCoil.parameterSpec = [\n {\n type: 'string',\n name: 'plcAddress',\n label: 'plc_address'\n },\n {\n type: 'string',\n name: 'value',\n label: 'expected_value'\n },\n {\n type: 'number',\n name: 'waitTerm',\n placeholder: 'milli-seconds',\n label: 'wait_term'\n }\n]\n\nMelsecWaitForCoil.help = 'integration/task/melsec-wait-coil'\n\nTaskRegistry.registerTaskHandler('melsec-wait-coil', MelsecWaitForCoil)\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const integration_base_1 = require("@things-factory/integration-base");
4
+ const melsec_plc_1 = require("../connector/melsec-plc");
5
+ const utils_1 = require("@things-factory/utils");
6
+ async function MelsecWriteCoil(step, { logger, domain }) {
7
+ var { connection: connectionName, params: { plcAddress: address, value, writeLength = 1, autoReset, delay = 50 } } = step;
8
+ var connection = integration_base_1.ConnectionManager.getConnectionInstanceByName(domain, connectionName);
9
+ if (!connection) {
10
+ throw new Error(`connection '${connectionName}' is not established.`);
11
+ }
12
+ var { request } = connection;
13
+ var w_address = address;
14
+ var w_value = value;
15
+ var deviceCode = w_address.substring(0, 1) + '*';
16
+ var af_address = Number(w_address.substring(1)).toString();
17
+ var len = af_address.length;
18
+ for (var i = 0; i < 6 - len; i++) {
19
+ af_address = '0' + af_address;
20
+ }
21
+ var writeStartDevice = af_address;
22
+ if (w_value == 1) {
23
+ var writeCoilValue = '1';
24
+ }
25
+ else {
26
+ var writeCoilValue = '0';
27
+ }
28
+ await doRequest(request, deviceCode, writeStartDevice, writeCoilValue, writeLength, logger);
29
+ if (autoReset) {
30
+ await (0, utils_1.sleep)(delay);
31
+ await doRequest(request, deviceCode, writeStartDevice, Number(!Number(writeCoilValue)), writeLength, logger);
32
+ }
33
+ return {
34
+ data: writeCoilValue
35
+ };
36
+ }
37
+ async function doRequest(request, deviceCode, writeStartDevice, writeCoilValue, writeLength, logger) {
38
+ var sendMessage = melsec_plc_1.MelsecPLCConnector.getWriteCoilCommand(deviceCode, writeStartDevice, writeCoilValue, writeLength);
39
+ // Request : 500000FF03FF000019000014010001M*00033300011
40
+ // Response : D00000FF03FF0000040000
41
+ var content = await request(sendMessage, 22, { logger });
42
+ // TODO writeLength 1이 아닐때 데이터 처리.
43
+ if (content.substring(17, 18) == '4') {
44
+ // ok
45
+ return {
46
+ data: writeCoilValue
47
+ };
48
+ }
49
+ else {
50
+ // error
51
+ throw new Error('response not applicable');
52
+ }
53
+ }
54
+ MelsecWriteCoil.parameterSpec = [
55
+ {
56
+ type: 'string',
57
+ name: 'plcAddress',
58
+ placeholder: 'M0,Y1,..',
59
+ label: 'plc_address'
60
+ },
61
+ {
62
+ type: 'number',
63
+ name: 'writeLength',
64
+ label: 'write_length'
65
+ },
66
+ {
67
+ type: 'number',
68
+ name: 'value',
69
+ label: 'value'
70
+ },
71
+ {
72
+ type: 'checkbox',
73
+ name: 'autoReset',
74
+ label: 'auto_reset'
75
+ },
76
+ {
77
+ type: 'number',
78
+ name: 'delay',
79
+ placeholder: 'milisecodes, default is 50ms',
80
+ label: 'reset_delay'
81
+ }
82
+ ];
83
+ MelsecWriteCoil.help = 'integration/task/melsec-write-coil';
84
+ integration_base_1.TaskRegistry.registerTaskHandler('melsec-write-coil', MelsecWriteCoil);
85
+ //# sourceMappingURL=melsec-write-coil.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"melsec-write-coil.js","sourceRoot":"","sources":["../../../server/engine/task/melsec-write-coil.ts"],"names":[],"mappings":"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","sourcesContent":["import { ConnectionManager, TaskRegistry } from '@things-factory/integration-base'\nimport { MelsecPLCConnector } from '../connector/melsec-plc'\n\nimport { sleep } from '@things-factory/utils'\n\nasync function MelsecWriteCoil(step, { logger, domain }) {\n var {\n connection: connectionName,\n params: { plcAddress: address, value, writeLength = 1, autoReset, delay = 50 }\n } = step\n\n var connection = ConnectionManager.getConnectionInstanceByName(domain, connectionName)\n if (!connection) {\n throw new Error(`connection '${connectionName}' is not established.`)\n }\n\n var { request } = connection\n\n var w_address = address\n var w_value = value\n var deviceCode = w_address.substring(0, 1) + '*'\n\n var af_address = Number(w_address.substring(1)).toString()\n var len = af_address.length\n for (var i = 0; i < 6 - len; i++) {\n af_address = '0' + af_address\n }\n var writeStartDevice = af_address\n\n if (w_value == 1) {\n var writeCoilValue = '1'\n } else {\n var writeCoilValue = '0'\n }\n\n await doRequest(request, deviceCode, writeStartDevice, writeCoilValue, writeLength, logger)\n\n if (autoReset) {\n await sleep(delay)\n\n await doRequest(request, deviceCode, writeStartDevice, Number(!Number(writeCoilValue)), writeLength, logger)\n }\n\n return {\n data: writeCoilValue\n }\n}\n\nasync function doRequest(request, deviceCode, writeStartDevice, writeCoilValue, writeLength, logger) {\n var sendMessage = MelsecPLCConnector.getWriteCoilCommand(deviceCode, writeStartDevice, writeCoilValue, writeLength)\n // Request : 500000FF03FF000019000014010001M*00033300011\n // Response : D00000FF03FF0000040000\n var content = await request(sendMessage, 22, { logger })\n\n // TODO writeLength 1이 아닐때 데이터 처리.\n if (content.substring(17, 18) == '4') {\n // ok\n return {\n data: writeCoilValue\n }\n } else {\n // error\n throw new Error('response not applicable')\n }\n}\n\nMelsecWriteCoil.parameterSpec = [\n {\n type: 'string',\n name: 'plcAddress',\n placeholder: 'M0,Y1,..',\n label: 'plc_address'\n },\n {\n type: 'number',\n name: 'writeLength',\n label: 'write_length'\n },\n {\n type: 'number',\n name: 'value',\n label: 'value'\n },\n {\n type: 'checkbox',\n name: 'autoReset',\n label: 'auto_reset'\n },\n {\n type: 'number',\n name: 'delay',\n placeholder: 'milisecodes, default is 50ms',\n label: 'reset_delay'\n }\n]\n\nMelsecWriteCoil.help = 'integration/task/melsec-write-coil'\n\nTaskRegistry.registerTaskHandler('melsec-write-coil', MelsecWriteCoil)\n"]}
@@ -0,0 +1 @@
1
+ export {};