@ya-modbus/emulator 0.7.1 → 0.9.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.
@@ -1 +1 @@
1
- {"version":3,"file":"emulator.js","sourceRoot":"","sources":["../../../src/emulator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"emulator.js","sourceRoot":"","sources":["../../../src/emulator.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,7 @@
1
1
  /**
2
2
  * RTU (serial) transport for Modbus emulator
3
3
  *
4
- * This implementation uses modbus-serial for protocol handling.
5
- * Serial port communication will be added in future iterations.
4
+ * This implementation uses modbus-serial ServerSerial for protocol handling.
6
5
  */
7
6
  import { BaseTransport } from './base.js';
8
7
  export interface RtuTransportConfig {
@@ -13,32 +12,30 @@ export interface RtuTransportConfig {
13
12
  stopBits?: 1 | 2;
14
13
  }
15
14
  export declare class RtuTransport extends BaseTransport {
15
+ private config;
16
16
  private requestHandler?;
17
+ private server?;
17
18
  private started;
18
- constructor(_config: RtuTransportConfig);
19
+ constructor(config: RtuTransportConfig);
19
20
  start(): Promise<void>;
20
21
  stop(): Promise<void>;
21
22
  send(_slaveId: number, _response: Buffer): Promise<void>;
22
23
  onRequest(handler: (slaveId: number, request: Buffer) => Promise<Buffer>): void;
23
24
  /**
24
- * Handle complete RTU frame (for future serial port implementation)
25
- * @internal
25
+ * Handle register read operations
26
26
  */
27
- handleFrame(frame: Buffer): Promise<void>;
27
+ private handleRegisterRead;
28
28
  /**
29
- * Calculate Modbus RTU CRC-16 (Modbus variant)
30
- *
31
- * Returns CRC as a 16-bit value that can be written with writeUInt16LE
29
+ * Handle register write operations
32
30
  */
33
- private calculateCRC;
31
+ private handleRegisterWrite;
34
32
  /**
35
- * Verify CRC of RTU frame
33
+ * Handle coil read operations
36
34
  */
37
- private verifyCRC;
35
+ private handleCoilRead;
38
36
  /**
39
- * Add CRC to buffer
40
- * @internal
37
+ * Handle coil write operations
41
38
  */
42
- addCRC(buffer: Buffer): Buffer;
39
+ private handleCoilWrite;
43
40
  }
44
41
  //# sourceMappingURL=rtu.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rtu.d.ts","sourceRoot":"","sources":["../../../../src/transports/rtu.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAEzC,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAA;IAChC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IAChB,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;CACjB;AAED,qBAAa,YAAa,SAAQ,aAAa;IAC7C,OAAO,CAAC,cAAc,CAAC,CAAuD;IAC9E,OAAO,CAAC,OAAO,CAAQ;gBAEX,OAAO,EAAE,kBAAkB;IAKvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IASrB,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQxD,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI;IAI/E;;;OAGG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmC/C;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAqBpB;;OAEG;IACH,OAAO,CAAC,SAAS;IAejB;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;CAO/B"}
1
+ {"version":3,"file":"rtu.d.ts","sourceRoot":"","sources":["../../../../src/transports/rtu.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAEzC,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAA;IAChC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IAChB,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;CACjB;AAED,qBAAa,YAAa,SAAQ,aAAa;IAC7C,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,cAAc,CAAC,CAAuD;IAC9E,OAAO,CAAC,MAAM,CAAC,CAAc;IAC7B,OAAO,CAAC,OAAO,CAAQ;gBAEX,MAAM,EAAE,kBAAkB;IAKhC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuEtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB3B,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxD,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI;IAI/E;;OAEG;YACW,kBAAkB;IAmChC;;OAEG;YACW,mBAAmB;IAqCjC;;OAEG;YACW,cAAc;IAiC5B;;OAEG;YACW,eAAe;CAoB9B"}
@@ -1,120 +1,214 @@
1
1
  /**
2
2
  * RTU (serial) transport for Modbus emulator
3
3
  *
4
- * This implementation uses modbus-serial for protocol handling.
5
- * Serial port communication will be added in future iterations.
4
+ * This implementation uses modbus-serial ServerSerial for protocol handling.
6
5
  */
6
+ import { ServerSerial } from 'modbus-serial';
7
7
  import { BaseTransport } from './base.js';
8
8
  export class RtuTransport extends BaseTransport {
9
- constructor(_config) {
9
+ constructor(config) {
10
10
  super();
11
11
  this.started = false;
12
- // Config stored for future serial port implementation
12
+ this.config = config;
13
13
  }
14
- start() {
15
- this.started = true;
16
- // Serial port initialization will be implemented when needed
17
- // For now, this is a placeholder for the interface
18
- return Promise.resolve();
14
+ async start() {
15
+ if (this.started) {
16
+ throw new Error('Transport already started');
17
+ }
18
+ // Create service vector that bridges modbus-serial callbacks to our request handler
19
+ const serviceVector = {
20
+ getHoldingRegister: async (addr, unitID) => {
21
+ return this.handleRegisterRead(unitID, 0x03, addr, 1);
22
+ },
23
+ getInputRegister: async (addr, unitID) => {
24
+ return this.handleRegisterRead(unitID, 0x04, addr, 1);
25
+ },
26
+ getMultipleHoldingRegisters: async (addr, length, unitID) => {
27
+ return this.handleRegisterRead(unitID, 0x03, addr, length);
28
+ },
29
+ getMultipleInputRegisters: async (addr, length, unitID) => {
30
+ return this.handleRegisterRead(unitID, 0x04, addr, length);
31
+ },
32
+ setRegister: async (addr, value, unitID) => {
33
+ return this.handleRegisterWrite(unitID, 0x06, addr, [value]);
34
+ },
35
+ setRegisterArray: async (addr, values, unitID) => {
36
+ return this.handleRegisterWrite(unitID, 0x10, addr, values);
37
+ },
38
+ getCoil: async (addr, unitID) => {
39
+ return this.handleCoilRead(unitID, 0x01, addr, 1);
40
+ },
41
+ getDiscreteInput: async (addr, unitID) => {
42
+ return this.handleCoilRead(unitID, 0x02, addr, 1);
43
+ },
44
+ setCoil: async (addr, value, unitID) => {
45
+ return this.handleCoilWrite(unitID, 0x05, addr, value);
46
+ },
47
+ };
48
+ // Build options with only defined serial port parameters
49
+ // Filter out undefined values to satisfy exactOptionalPropertyTypes
50
+ const options = Object.fromEntries(Object.entries({
51
+ path: this.config.port,
52
+ unitID: 255, // Listen to all unit IDs
53
+ baudRate: this.config.baudRate,
54
+ parity: this.config.parity,
55
+ dataBits: this.config.dataBits,
56
+ stopBits: this.config.stopBits,
57
+ }).filter(([, value]) => value !== undefined));
58
+ // Create and start server
59
+ return new Promise((resolve, reject) => {
60
+ this.server = new ServerSerial(serviceVector, {
61
+ ...options,
62
+ openCallback: (err) => {
63
+ if (err) {
64
+ reject(err);
65
+ }
66
+ else {
67
+ this.started = true;
68
+ resolve();
69
+ }
70
+ },
71
+ });
72
+ // Handle errors
73
+ this.server.on('error', (err) => {
74
+ // Log error but don't stop server
75
+ console.error('RTU transport error:', err);
76
+ });
77
+ });
19
78
  }
20
- stop() {
21
- if (!this.started) {
22
- return Promise.resolve();
79
+ async stop() {
80
+ if (!this.started || !this.server) {
81
+ return;
23
82
  }
24
- this.started = false;
25
- // Serial port cleanup will be implemented when needed
26
- return Promise.resolve();
83
+ return new Promise((resolve, reject) => {
84
+ if (!this.server) {
85
+ resolve();
86
+ return;
87
+ }
88
+ this.server.close((err) => {
89
+ if (err) {
90
+ reject(err);
91
+ }
92
+ else {
93
+ this.started = false;
94
+ delete this.server;
95
+ resolve();
96
+ }
97
+ });
98
+ });
27
99
  }
28
100
  send(_slaveId, _response) {
29
101
  if (!this.started) {
30
102
  return Promise.reject(new Error('Transport not started'));
31
103
  }
32
- // Response sending will be implemented with serial port
104
+ // Responses are sent automatically by modbus-serial server
105
+ // This method is kept for interface compatibility
33
106
  return Promise.resolve();
34
107
  }
35
108
  onRequest(handler) {
36
109
  this.requestHandler = handler;
37
110
  }
38
111
  /**
39
- * Handle complete RTU frame (for future serial port implementation)
40
- * @internal
112
+ * Handle register read operations
41
113
  */
42
- async handleFrame(frame) {
43
- // Minimum frame: slave_id + function_code + CRC (4 bytes)
44
- if (frame.length < 4) {
45
- return;
46
- }
47
- // Verify CRC
48
- if (!this.verifyCRC(frame)) {
49
- return;
50
- }
51
- // Extract slave ID (safe after length check)
52
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
53
- const slaveId = frame[0];
54
- // Remove CRC to get request data
55
- const request = frame.subarray(0, frame.length - 2);
114
+ async handleRegisterRead(unitID, functionCode, addr, length) {
56
115
  if (!this.requestHandler) {
57
- return;
116
+ throw new Error('No request handler set');
58
117
  }
59
- try {
60
- // Get response from handler
61
- const response = await this.requestHandler(slaveId, request);
62
- // Send response (null check required by exactOptionalPropertyTypes)
63
- if (response !== undefined) {
64
- await this.send(slaveId, response);
65
- }
118
+ // Build Modbus request buffer
119
+ const request = Buffer.alloc(6);
120
+ request[0] = unitID;
121
+ request[1] = functionCode;
122
+ request.writeUInt16BE(addr, 2);
123
+ request.writeUInt16BE(length, 4);
124
+ // Call handler
125
+ const response = await this.requestHandler(unitID, request);
126
+ // Parse response
127
+ const byteCount = response[2];
128
+ if (byteCount === undefined || response.length < 3 + byteCount) {
129
+ throw new Error('Invalid response');
66
130
  }
67
- catch {
68
- // Don't send response if handler fails
131
+ // Extract register values
132
+ const values = [];
133
+ for (let i = 0; i < byteCount / 2; i++) {
134
+ values.push(response.readUInt16BE(3 + i * 2));
69
135
  }
136
+ return values;
70
137
  }
71
138
  /**
72
- * Calculate Modbus RTU CRC-16 (Modbus variant)
73
- *
74
- * Returns CRC as a 16-bit value that can be written with writeUInt16LE
139
+ * Handle register write operations
75
140
  */
76
- calculateCRC(buffer) {
77
- let crc = 0xffff;
78
- for (let i = 0; i < buffer.length; i++) {
79
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
80
- crc ^= buffer[i];
81
- for (let j = 0; j < 8; j++) {
82
- if (crc & 0x0001) {
83
- crc = (crc >> 1) ^ 0xa001;
84
- }
85
- else {
86
- crc = crc >> 1;
87
- }
141
+ async handleRegisterWrite(unitID, functionCode, addr, values) {
142
+ if (!this.requestHandler) {
143
+ throw new Error('No request handler set');
144
+ }
145
+ // Build Modbus request buffer
146
+ let request;
147
+ if (functionCode === 0x06) {
148
+ // Write single register
149
+ request = Buffer.alloc(6);
150
+ request[0] = unitID;
151
+ request[1] = functionCode;
152
+ request.writeUInt16BE(addr, 2);
153
+ request.writeUInt16BE(values[0] ?? 0, 4);
154
+ }
155
+ else {
156
+ // Write multiple registers
157
+ const byteCount = values.length * 2;
158
+ request = Buffer.alloc(7 + byteCount);
159
+ request[0] = unitID;
160
+ request[1] = functionCode;
161
+ request.writeUInt16BE(addr, 2);
162
+ request.writeUInt16BE(values.length, 4);
163
+ request[6] = byteCount;
164
+ for (let i = 0; i < values.length; i++) {
165
+ request.writeUInt16BE(values[i] ?? 0, 7 + i * 2);
88
166
  }
89
167
  }
90
- // Swap bytes for little-endian representation
91
- // CRC is stored low byte first in Modbus RTU
92
- return ((crc & 0xff) << 8) | ((crc >> 8) & 0xff);
168
+ // Call handler and ignore response
169
+ await this.requestHandler(unitID, request);
93
170
  }
94
171
  /**
95
- * Verify CRC of RTU frame
172
+ * Handle coil read operations
96
173
  */
97
- verifyCRC(frame) {
98
- if (frame.length < 4) {
99
- return false;
174
+ async handleCoilRead(unitID, functionCode, addr, length) {
175
+ if (!this.requestHandler) {
176
+ throw new Error('No request handler set');
177
+ }
178
+ // Build Modbus request buffer
179
+ const request = Buffer.alloc(6);
180
+ request[0] = unitID;
181
+ request[1] = functionCode;
182
+ request.writeUInt16BE(addr, 2);
183
+ request.writeUInt16BE(length, 4);
184
+ // Call handler
185
+ const response = await this.requestHandler(unitID, request);
186
+ // Parse response - get first bit from first byte of coil data
187
+ const byteCount = response[2];
188
+ if (byteCount === undefined || response.length < 4) {
189
+ throw new Error('Invalid response');
100
190
  }
101
- // Get CRC from frame (last 2 bytes, little-endian)
102
- const receivedCRC = frame.readUInt16LE(frame.length - 2);
103
- // Calculate CRC of data (everything except last 2 bytes)
104
- const data = frame.subarray(0, frame.length - 2);
105
- const calculatedCRC = this.calculateCRC(data);
106
- return receivedCRC === calculatedCRC;
191
+ const coilByte = response[3];
192
+ if (coilByte === undefined) {
193
+ throw new Error('Invalid response');
194
+ }
195
+ return (coilByte & 0x01) === 1;
107
196
  }
108
197
  /**
109
- * Add CRC to buffer
110
- * @internal
198
+ * Handle coil write operations
111
199
  */
112
- addCRC(buffer) {
113
- const crc = this.calculateCRC(buffer);
114
- const result = Buffer.alloc(buffer.length + 2);
115
- buffer.copy(result);
116
- result.writeUInt16LE(crc, buffer.length);
117
- return result;
200
+ async handleCoilWrite(unitID, functionCode, addr, value) {
201
+ if (!this.requestHandler) {
202
+ throw new Error('No request handler set');
203
+ }
204
+ // Build Modbus request buffer
205
+ const request = Buffer.alloc(6);
206
+ request[0] = unitID;
207
+ request[1] = functionCode;
208
+ request.writeUInt16BE(addr, 2);
209
+ request.writeUInt16BE(value ? 0xff00 : 0x0000, 4);
210
+ // Call handler and ignore response
211
+ await this.requestHandler(unitID, request);
118
212
  }
119
213
  }
120
214
  //# sourceMappingURL=rtu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rtu.js","sourceRoot":"","sources":["../../../../src/transports/rtu.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAUzC,MAAM,OAAO,YAAa,SAAQ,aAAa;IAI7C,YAAY,OAA2B;QACrC,KAAK,EAAE,CAAA;QAHD,YAAO,GAAG,KAAK,CAAA;QAIrB,sDAAsD;IACxD,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,6DAA6D;QAC7D,mDAAmD;QACnD,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;IAC1B,CAAC;IAED,IAAI;QACF,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;QAC1B,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;QACpB,sDAAsD;QACtD,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;IAC1B,CAAC;IAED,IAAI,CAAC,QAAgB,EAAE,SAAiB;QACtC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAA;QAC3D,CAAC;QACD,wDAAwD;QACxD,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;IAC1B,CAAC;IAED,SAAS,CAAC,OAA8D;QACtE,IAAI,CAAC,cAAc,GAAG,OAAO,CAAA;IAC/B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,WAAW,CAAC,KAAa;QAC7B,0DAA0D;QAC1D,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,OAAM;QACR,CAAC;QAED,aAAa;QACb,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAM;QACR,CAAC;QAED,6CAA6C;QAC7C,oEAAoE;QACpE,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAE,CAAA;QAEzB,iCAAiC;QACjC,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAEnD,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,OAAM;QACR,CAAC;QAED,IAAI,CAAC;YACH,4BAA4B;YAC5B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YAE5D,oEAAoE;YACpE,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC3B,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;YACpC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,uCAAuC;QACzC,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,YAAY,CAAC,MAAc;QACjC,IAAI,GAAG,GAAG,MAAM,CAAA;QAEhB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,oEAAoE;YACpE,GAAG,IAAI,MAAM,CAAC,CAAC,CAAE,CAAA;YAEjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3B,IAAI,GAAG,GAAG,MAAM,EAAE,CAAC;oBACjB,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,MAAM,CAAA;gBAC3B,CAAC;qBAAM,CAAC;oBACN,GAAG,GAAG,GAAG,IAAI,CAAC,CAAA;gBAChB,CAAC;YACH,CAAC;QACH,CAAC;QAED,8CAA8C;QAC9C,6CAA6C;QAC7C,OAAO,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IAClD,CAAC;IAED;;OAEG;IACK,SAAS,CAAC,KAAa;QAC7B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,KAAK,CAAA;QACd,CAAC;QAED,mDAAmD;QACnD,MAAM,WAAW,GAAG,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAExD,yDAAyD;QACzD,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAChD,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAA;QAE7C,OAAO,WAAW,KAAK,aAAa,CAAA;IACtC,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,MAAc;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;QACrC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAC9C,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACnB,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;QACxC,OAAO,MAAM,CAAA;IACf,CAAC;CACF"}
1
+ {"version":3,"file":"rtu.js","sourceRoot":"","sources":["../../../../src/transports/rtu.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * TCP transport for Modbus emulator
3
+ *
4
+ * This implementation uses modbus-serial ServerTCP for protocol handling.
5
+ */
6
+ import { BaseTransport } from './base.js';
7
+ export interface TcpTransportConfig {
8
+ host: string;
9
+ port: number;
10
+ }
11
+ export declare class TcpTransport extends BaseTransport {
12
+ private config;
13
+ private requestHandler?;
14
+ private server?;
15
+ private started;
16
+ constructor(config: TcpTransportConfig);
17
+ start(): Promise<void>;
18
+ stop(): Promise<void>;
19
+ send(_slaveId: number, _response: Buffer): Promise<void>;
20
+ onRequest(handler: (slaveId: number, request: Buffer) => Promise<Buffer>): void;
21
+ /**
22
+ * Handle register read operations
23
+ */
24
+ private handleRegisterRead;
25
+ /**
26
+ * Handle register write operations
27
+ */
28
+ private handleRegisterWrite;
29
+ /**
30
+ * Handle coil read operations
31
+ */
32
+ private handleCoilRead;
33
+ /**
34
+ * Handle coil write operations
35
+ */
36
+ private handleCoilWrite;
37
+ }
38
+ //# sourceMappingURL=tcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tcp.d.ts","sourceRoot":"","sources":["../../../../src/transports/tcp.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAEzC,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAED,qBAAa,YAAa,SAAQ,aAAa;IAC7C,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,cAAc,CAAC,CAAuD;IAC9E,OAAO,CAAC,MAAM,CAAC,CAAW;IAC1B,OAAO,CAAC,OAAO,CAAQ;gBAEX,MAAM,EAAE,kBAAkB;IAKhC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA8DtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB3B,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxD,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI;IAI/E;;OAEG;YACW,kBAAkB;IAmChC;;OAEG;YACW,mBAAmB;IAqCjC;;OAEG;YACW,cAAc;IAiC5B;;OAEG;YACW,eAAe;CAoB9B"}
@@ -0,0 +1,205 @@
1
+ /**
2
+ * TCP transport for Modbus emulator
3
+ *
4
+ * This implementation uses modbus-serial ServerTCP for protocol handling.
5
+ */
6
+ import { ServerTCP } from 'modbus-serial';
7
+ import { BaseTransport } from './base.js';
8
+ export class TcpTransport extends BaseTransport {
9
+ constructor(config) {
10
+ super();
11
+ this.started = false;
12
+ this.config = config;
13
+ }
14
+ async start() {
15
+ if (this.started) {
16
+ throw new Error('Transport already started');
17
+ }
18
+ // Create service vector that bridges modbus-serial callbacks to our request handler
19
+ const serviceVector = {
20
+ getHoldingRegister: async (addr, unitID) => {
21
+ return this.handleRegisterRead(unitID, 0x03, addr, 1);
22
+ },
23
+ getInputRegister: async (addr, unitID) => {
24
+ return this.handleRegisterRead(unitID, 0x04, addr, 1);
25
+ },
26
+ getMultipleHoldingRegisters: async (addr, length, unitID) => {
27
+ return this.handleRegisterRead(unitID, 0x03, addr, length);
28
+ },
29
+ getMultipleInputRegisters: async (addr, length, unitID) => {
30
+ return this.handleRegisterRead(unitID, 0x04, addr, length);
31
+ },
32
+ setRegister: async (addr, value, unitID) => {
33
+ return this.handleRegisterWrite(unitID, 0x06, addr, [value]);
34
+ },
35
+ setRegisterArray: async (addr, values, unitID) => {
36
+ return this.handleRegisterWrite(unitID, 0x10, addr, values);
37
+ },
38
+ getCoil: async (addr, unitID) => {
39
+ return this.handleCoilRead(unitID, 0x01, addr, 1);
40
+ },
41
+ getDiscreteInput: async (addr, unitID) => {
42
+ return this.handleCoilRead(unitID, 0x02, addr, 1);
43
+ },
44
+ setCoil: async (addr, value, unitID) => {
45
+ return this.handleCoilWrite(unitID, 0x05, addr, value);
46
+ },
47
+ };
48
+ // Build options - all values are required for TCP
49
+ const options = {
50
+ host: this.config.host,
51
+ port: this.config.port,
52
+ unitID: 255, // Listen to all unit IDs
53
+ };
54
+ // Create server
55
+ const server = new ServerTCP(serviceVector, options);
56
+ this.server = server;
57
+ // Wait for initialized event
58
+ return new Promise((resolve) => {
59
+ server.on('initialized', () => {
60
+ this.started = true;
61
+ resolve();
62
+ });
63
+ // Handle errors
64
+ server.on('error', (err) => {
65
+ // Log error but don't stop server
66
+ console.error('TCP transport error:', err);
67
+ });
68
+ });
69
+ }
70
+ async stop() {
71
+ if (!this.started || !this.server) {
72
+ return;
73
+ }
74
+ return new Promise((resolve, reject) => {
75
+ if (!this.server) {
76
+ resolve();
77
+ return;
78
+ }
79
+ this.server.close((err) => {
80
+ if (err) {
81
+ reject(err);
82
+ }
83
+ else {
84
+ this.started = false;
85
+ delete this.server;
86
+ resolve();
87
+ }
88
+ });
89
+ });
90
+ }
91
+ send(_slaveId, _response) {
92
+ if (!this.started) {
93
+ return Promise.reject(new Error('Transport not started'));
94
+ }
95
+ // Responses are sent automatically by modbus-serial server
96
+ // This method is kept for interface compatibility
97
+ return Promise.resolve();
98
+ }
99
+ onRequest(handler) {
100
+ this.requestHandler = handler;
101
+ }
102
+ /**
103
+ * Handle register read operations
104
+ */
105
+ async handleRegisterRead(unitID, functionCode, addr, length) {
106
+ if (!this.requestHandler) {
107
+ throw new Error('No request handler set');
108
+ }
109
+ // Build Modbus request buffer
110
+ const request = Buffer.alloc(6);
111
+ request[0] = unitID;
112
+ request[1] = functionCode;
113
+ request.writeUInt16BE(addr, 2);
114
+ request.writeUInt16BE(length, 4);
115
+ // Call handler
116
+ const response = await this.requestHandler(unitID, request);
117
+ // Parse response
118
+ const byteCount = response[2];
119
+ if (byteCount === undefined || response.length < 3 + byteCount) {
120
+ throw new Error('Invalid response');
121
+ }
122
+ // Extract register values
123
+ const values = [];
124
+ for (let i = 0; i < byteCount / 2; i++) {
125
+ values.push(response.readUInt16BE(3 + i * 2));
126
+ }
127
+ return values;
128
+ }
129
+ /**
130
+ * Handle register write operations
131
+ */
132
+ async handleRegisterWrite(unitID, functionCode, addr, values) {
133
+ if (!this.requestHandler) {
134
+ throw new Error('No request handler set');
135
+ }
136
+ // Build Modbus request buffer
137
+ let request;
138
+ if (functionCode === 0x06) {
139
+ // Write single register
140
+ request = Buffer.alloc(6);
141
+ request[0] = unitID;
142
+ request[1] = functionCode;
143
+ request.writeUInt16BE(addr, 2);
144
+ request.writeUInt16BE(values[0] ?? 0, 4);
145
+ }
146
+ else {
147
+ // Write multiple registers
148
+ const byteCount = values.length * 2;
149
+ request = Buffer.alloc(7 + byteCount);
150
+ request[0] = unitID;
151
+ request[1] = functionCode;
152
+ request.writeUInt16BE(addr, 2);
153
+ request.writeUInt16BE(values.length, 4);
154
+ request[6] = byteCount;
155
+ for (let i = 0; i < values.length; i++) {
156
+ request.writeUInt16BE(values[i] ?? 0, 7 + i * 2);
157
+ }
158
+ }
159
+ // Call handler and ignore response
160
+ await this.requestHandler(unitID, request);
161
+ }
162
+ /**
163
+ * Handle coil read operations
164
+ */
165
+ async handleCoilRead(unitID, functionCode, addr, length) {
166
+ if (!this.requestHandler) {
167
+ throw new Error('No request handler set');
168
+ }
169
+ // Build Modbus request buffer
170
+ const request = Buffer.alloc(6);
171
+ request[0] = unitID;
172
+ request[1] = functionCode;
173
+ request.writeUInt16BE(addr, 2);
174
+ request.writeUInt16BE(length, 4);
175
+ // Call handler
176
+ const response = await this.requestHandler(unitID, request);
177
+ // Parse response - get first bit from first byte of coil data
178
+ const byteCount = response[2];
179
+ if (byteCount === undefined || response.length < 4) {
180
+ throw new Error('Invalid response');
181
+ }
182
+ const coilByte = response[3];
183
+ if (coilByte === undefined) {
184
+ throw new Error('Invalid response');
185
+ }
186
+ return (coilByte & 0x01) === 1;
187
+ }
188
+ /**
189
+ * Handle coil write operations
190
+ */
191
+ async handleCoilWrite(unitID, functionCode, addr, value) {
192
+ if (!this.requestHandler) {
193
+ throw new Error('No request handler set');
194
+ }
195
+ // Build Modbus request buffer
196
+ const request = Buffer.alloc(6);
197
+ request[0] = unitID;
198
+ request[1] = functionCode;
199
+ request.writeUInt16BE(addr, 2);
200
+ request.writeUInt16BE(value ? 0xff00 : 0x0000, 4);
201
+ // Call handler and ignore response
202
+ await this.requestHandler(unitID, request);
203
+ }
204
+ }
205
+ //# sourceMappingURL=tcp.js.map