@totemsdk/edge-modbus 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/gateway.d.ts CHANGED
@@ -1,25 +1,36 @@
1
1
  /**
2
2
  * Modbus Edge Gateway — wires a ModbusTransportPort into an EdgeRuntime.
3
+ *
4
+ * Supports Modbus RTU frame format (no MBAP header) to match the Go native binary.
5
+ * The Go binary parses frame[0] as unitId and frame[1] as functionCode, which
6
+ * is correct for RTU but would misparse TCP frames.
3
7
  */
4
8
  import type { EdgeRuntime, EdgeOperationResult } from '@totemsdk/edge';
5
9
  import type { ModbusTransportPort } from './transport.js';
6
10
  export interface ModbusGatewayConfig {
7
11
  runtime: EdgeRuntime;
8
12
  transport: ModbusTransportPort;
9
- /** Map unit IDs to sensor/device identifiers. */
10
13
  unitMap?: Record<number, string>;
11
14
  }
12
15
  export interface ModbusGateway {
13
16
  start(): Promise<void>;
14
17
  stop(): Promise<void>;
15
18
  readonly status: 'stopped' | 'running' | 'error';
16
- /** Read coils (function code 1). */
17
19
  readCoils(unitId: number, address: number, count: number): Promise<EdgeOperationResult<{
18
20
  values: boolean[];
19
21
  }>>;
20
- /** Read holding registers (function code 3). */
21
- readRegisters(unitId: number, address: number, count: number): Promise<EdgeOperationResult<{
22
+ readDiscreteInputs(unitId: number, address: number, count: number): Promise<EdgeOperationResult<{
23
+ values: boolean[];
24
+ }>>;
25
+ readHoldingRegisters(unitId: number, address: number, count: number): Promise<EdgeOperationResult<{
26
+ values: number[];
27
+ }>>;
28
+ readInputRegisters(unitId: number, address: number, count: number): Promise<EdgeOperationResult<{
22
29
  values: number[];
23
30
  }>>;
31
+ writeSingleCoil(unitId: number, address: number, value: boolean): Promise<EdgeOperationResult<void>>;
32
+ writeSingleRegister(unitId: number, address: number, value: number): Promise<EdgeOperationResult<void>>;
33
+ writeMultipleCoils(unitId: number, address: number, values: boolean[]): Promise<EdgeOperationResult<void>>;
34
+ writeMultipleRegisters(unitId: number, address: number, values: number[]): Promise<EdgeOperationResult<void>>;
24
35
  }
25
36
  export declare function createModbusGateway(config: ModbusGatewayConfig): ModbusGateway;
package/dist/gateway.js CHANGED
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Modbus Edge Gateway — wires a ModbusTransportPort into an EdgeRuntime.
4
+ *
5
+ * Supports Modbus RTU frame format (no MBAP header) to match the Go native binary.
6
+ * The Go binary parses frame[0] as unitId and frame[1] as functionCode, which
7
+ * is correct for RTU but would misparse TCP frames.
4
8
  */
5
9
  Object.defineProperty(exports, "__esModule", { value: true });
6
10
  exports.createModbusGateway = createModbusGateway;
@@ -14,8 +18,8 @@ function createModbusGateway(config) {
14
18
  if (status === 'running')
15
19
  return;
16
20
  await config.transport.connect();
17
- unsubFrame = config.transport.onFrame((frame) => {
18
- // Frames are dispatched by the sensor bridge
21
+ unsubFrame = config.transport.onFrame((_frame) => {
22
+ // Unsolicited frames are not expected in Modbus request/response model
19
23
  });
20
24
  unsubError = config.transport.onError(() => {
21
25
  status = 'error';
@@ -29,62 +33,159 @@ function createModbusGateway(config) {
29
33
  status = 'stopped';
30
34
  },
31
35
  async readCoils(unitId, address, count) {
32
- try {
33
- const request = buildModbusFrame(unitId, 1, address, count);
34
- const response = await config.transport.sendFrame(request);
35
- const values = parseCoilResponse(response, count);
36
- return { ok: true, data: { values } };
37
- }
38
- catch (e) {
39
- return { ok: false, error: String(e) };
40
- }
36
+ return readBits(config.transport, unitId, 1, address, count);
41
37
  },
42
- async readRegisters(unitId, address, count) {
43
- try {
44
- const request = buildModbusFrame(unitId, 3, address, count);
45
- const response = await config.transport.sendFrame(request);
46
- const values = parseRegisterResponse(response, count);
47
- return { ok: true, data: { values } };
48
- }
49
- catch (e) {
50
- return { ok: false, error: String(e) };
51
- }
38
+ async readDiscreteInputs(unitId, address, count) {
39
+ return readBits(config.transport, unitId, 2, address, count);
40
+ },
41
+ async readHoldingRegisters(unitId, address, count) {
42
+ return readRegisters(config.transport, unitId, 3, address, count);
43
+ },
44
+ async readInputRegisters(unitId, address, count) {
45
+ return readRegisters(config.transport, unitId, 4, address, count);
46
+ },
47
+ async writeSingleCoil(unitId, address, value) {
48
+ return writeSingle(config.transport, unitId, 5, address, value ? 0xFF00 : 0x0000);
49
+ },
50
+ async writeSingleRegister(unitId, address, value) {
51
+ return writeSingle(config.transport, unitId, 6, address, value);
52
+ },
53
+ async writeMultipleCoils(unitId, address, values) {
54
+ return writeMultipleCoilsImpl(config.transport, unitId, address, values);
55
+ },
56
+ async writeMultipleRegisters(unitId, address, values) {
57
+ return writeMultipleRegistersImpl(config.transport, unitId, address, values);
52
58
  },
53
59
  };
54
60
  }
55
- function buildModbusFrame(unitId, functionCode, address, count) {
61
+ // ── RTU frame builders (no MBAP header — matches Go binary) ──────────────
62
+ function buildReadFrame(unitId, fc, address, count) {
63
+ const buf = new Uint8Array(8);
64
+ buf[0] = unitId;
65
+ buf[1] = fc;
66
+ new DataView(buf.buffer).setUint16(2, address, false);
67
+ new DataView(buf.buffer).setUint16(4, count, false);
68
+ // CRC placeholder (bytes 6-7) — Go library handles CRC internally
69
+ buf[6] = 0;
70
+ buf[7] = 0;
71
+ return buf;
72
+ }
73
+ function buildWriteSingleFrame(unitId, fc, address, value) {
56
74
  const buf = new Uint8Array(8);
57
- buf[0] = 0;
58
- buf[1] = 0; // transaction ID
59
- buf[2] = 0;
60
- buf[3] = 0; // protocol ID
61
- buf[4] = 0;
62
- buf[5] = 2; // length
63
- buf[6] = unitId;
64
- buf[7] = functionCode;
65
- const addr = new Uint8Array(2);
66
- new DataView(addr.buffer).setUint16(0, address, false);
67
- const cnt = new Uint8Array(2);
68
- new DataView(cnt.buffer).setUint16(0, count, false);
69
- const result = new Uint8Array(8 + 4);
70
- result.set(buf);
71
- result.set(addr, 8);
72
- result.set(cnt, 10);
73
- return result;
75
+ buf[0] = unitId;
76
+ buf[1] = fc;
77
+ new DataView(buf.buffer).setUint16(2, address, false);
78
+ new DataView(buf.buffer).setUint16(4, value, false);
79
+ buf[6] = 0;
80
+ buf[7] = 0;
81
+ return buf;
74
82
  }
75
- function parseCoilResponse(response, count) {
83
+ function buildWriteMultipleCoilsFrame(unitId, address, values) {
84
+ const byteCount = Math.ceil(values.length / 8);
85
+ const buf = new Uint8Array(7 + byteCount);
86
+ buf[0] = unitId;
87
+ buf[1] = 15; // FC 15
88
+ new DataView(buf.buffer).setUint16(2, address, false);
89
+ new DataView(buf.buffer).setUint16(4, values.length, false);
90
+ buf[6] = byteCount;
91
+ for (let i = 0; i < values.length; i++) {
92
+ if (values[i]) {
93
+ buf[7 + Math.floor(i / 8)] |= (1 << (i % 8));
94
+ }
95
+ }
96
+ return buf;
97
+ }
98
+ function buildWriteMultipleRegistersFrame(unitId, address, values) {
99
+ const byteCount = values.length * 2;
100
+ const buf = new Uint8Array(7 + byteCount);
101
+ buf[0] = unitId;
102
+ buf[1] = 16; // FC 16
103
+ new DataView(buf.buffer).setUint16(2, address, false);
104
+ new DataView(buf.buffer).setUint16(4, values.length, false);
105
+ buf[6] = byteCount;
106
+ for (let i = 0; i < values.length; i++) {
107
+ new DataView(buf.buffer).setUint16(7 + i * 2, values[i], false);
108
+ }
109
+ return buf;
110
+ }
111
+ // ── Response parsers (RTU format — no MBAP header) ────────────────────────
112
+ function checkException(response) {
113
+ if (response.length < 2)
114
+ return;
115
+ const fc = response[1];
116
+ if (fc & 0x80) {
117
+ const exceptionCode = response.length >= 3 ? response[2] : 0;
118
+ throw new Error(`Modbus exception: function=${fc & 0x7F} code=${exceptionCode}`);
119
+ }
120
+ }
121
+ function parseBitResponse(response, count) {
122
+ checkException(response);
76
123
  const values = [];
77
124
  for (let i = 0; i < count; i++) {
78
- const byte = response[9 + Math.floor(i / 8)] ?? 0;
125
+ const byte = response[3 + Math.floor(i / 8)] ?? 0;
79
126
  values.push(((byte >> (i % 8)) & 1) === 1);
80
127
  }
81
128
  return values;
82
129
  }
83
130
  function parseRegisterResponse(response, count) {
131
+ checkException(response);
84
132
  const values = [];
85
133
  for (let i = 0; i < count; i++) {
86
- const offset = 9 + i * 2;
87
- values.push(new DataView(response.buffer, response.byteOffset + offset, 2).getUint16(0, false));
134
+ values.push(new DataView(response.buffer, response.byteOffset + 3 + i * 2, 2).getUint16(0, false));
88
135
  }
89
136
  return values;
90
137
  }
138
+ // ── Operation implementations ─────────────────────────────────────────────
139
+ async function readBits(transport, unitId, fc, address, count) {
140
+ try {
141
+ const request = buildReadFrame(unitId, fc, address, count);
142
+ const response = await transport.sendFrame(request);
143
+ return { ok: true, data: { values: parseBitResponse(response, count) } };
144
+ }
145
+ catch (e) {
146
+ return { ok: false, error: String(e) };
147
+ }
148
+ }
149
+ async function readRegisters(transport, unitId, fc, address, count) {
150
+ try {
151
+ const request = buildReadFrame(unitId, fc, address, count);
152
+ const response = await transport.sendFrame(request);
153
+ return { ok: true, data: { values: parseRegisterResponse(response, count) } };
154
+ }
155
+ catch (e) {
156
+ return { ok: false, error: String(e) };
157
+ }
158
+ }
159
+ async function writeSingle(transport, unitId, fc, address, value) {
160
+ try {
161
+ const request = buildWriteSingleFrame(unitId, fc, address, value);
162
+ const response = await transport.sendFrame(request);
163
+ checkException(response);
164
+ return { ok: true };
165
+ }
166
+ catch (e) {
167
+ return { ok: false, error: String(e) };
168
+ }
169
+ }
170
+ async function writeMultipleCoilsImpl(transport, unitId, address, values) {
171
+ try {
172
+ const request = buildWriteMultipleCoilsFrame(unitId, address, values);
173
+ const response = await transport.sendFrame(request);
174
+ checkException(response);
175
+ return { ok: true };
176
+ }
177
+ catch (e) {
178
+ return { ok: false, error: String(e) };
179
+ }
180
+ }
181
+ async function writeMultipleRegistersImpl(transport, unitId, address, values) {
182
+ try {
183
+ const request = buildWriteMultipleRegistersFrame(unitId, address, values);
184
+ const response = await transport.sendFrame(request);
185
+ checkException(response);
186
+ return { ok: true };
187
+ }
188
+ catch (e) {
189
+ return { ok: false, error: String(e) };
190
+ }
191
+ }
package/dist/index.d.ts CHANGED
@@ -3,3 +3,5 @@ export { createModbusGateway } from './gateway.js';
3
3
  export type { ModbusGatewayConfig, ModbusGateway } from './gateway.js';
4
4
  export { createModbusSensorBridge } from './sensor-bridge.js';
5
5
  export type { ModbusSensorBinding, ModbusSensorBridgeConfig, ModbusSensorBridge } from './sensor-bridge.js';
6
+ export { NativeModbusTransport } from './native-transport.js';
7
+ export type { NativeModbusConfig } from './native-transport.js';
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createModbusSensorBridge = exports.createModbusGateway = void 0;
3
+ exports.NativeModbusTransport = exports.createModbusSensorBridge = exports.createModbusGateway = void 0;
4
4
  var gateway_js_1 = require("./gateway.js");
5
5
  Object.defineProperty(exports, "createModbusGateway", { enumerable: true, get: function () { return gateway_js_1.createModbusGateway; } });
6
6
  var sensor_bridge_js_1 = require("./sensor-bridge.js");
7
7
  Object.defineProperty(exports, "createModbusSensorBridge", { enumerable: true, get: function () { return sensor_bridge_js_1.createModbusSensorBridge; } });
8
+ var native_transport_js_1 = require("./native-transport.js");
9
+ Object.defineProperty(exports, "NativeModbusTransport", { enumerable: true, get: function () { return native_transport_js_1.NativeModbusTransport; } });
@@ -0,0 +1,36 @@
1
+ /**
2
+ * NativeModbusTransport — connects to the edge-modbus Go binary over TCP.
3
+ *
4
+ * The Go binary listens on a local TCP socket (default 127.0.0.1:15002)
5
+ * and accepts newline-delimited JSON requests. This class implements
6
+ * ModbusTransportPort by forwarding all calls to the Go process.
7
+ *
8
+ * Usage:
9
+ * const transport = new NativeModbusTransport({ host: '127.0.0.1', port: 15002 });
10
+ * await transport.connect();
11
+ * const response = await transport.sendFrame(requestFrame);
12
+ * transport.disconnect();
13
+ */
14
+ import type { ModbusTransportPort } from './transport.js';
15
+ export interface NativeModbusConfig {
16
+ host?: string;
17
+ port?: number;
18
+ /** Connection timeout in ms. Default 5000. */
19
+ connectTimeoutMs?: number;
20
+ /** Per-request timeout in ms. Default 10000. */
21
+ requestTimeoutMs?: number;
22
+ }
23
+ export declare class NativeModbusTransport implements ModbusTransportPort {
24
+ private socket;
25
+ private buffer;
26
+ private pending;
27
+ private frameHandlers;
28
+ private errorHandlers;
29
+ private readonly config;
30
+ constructor(config?: NativeModbusConfig);
31
+ connect(): Promise<void>;
32
+ disconnect(): Promise<void>;
33
+ sendFrame(frame: Uint8Array): Promise<Uint8Array>;
34
+ onFrame(handler: (frame: Uint8Array) => void): () => void;
35
+ onError(handler: (err: Error) => void): () => void;
36
+ }
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ /**
3
+ * NativeModbusTransport — connects to the edge-modbus Go binary over TCP.
4
+ *
5
+ * The Go binary listens on a local TCP socket (default 127.0.0.1:15002)
6
+ * and accepts newline-delimited JSON requests. This class implements
7
+ * ModbusTransportPort by forwarding all calls to the Go process.
8
+ *
9
+ * Usage:
10
+ * const transport = new NativeModbusTransport({ host: '127.0.0.1', port: 15002 });
11
+ * await transport.connect();
12
+ * const response = await transport.sendFrame(requestFrame);
13
+ * transport.disconnect();
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.NativeModbusTransport = void 0;
17
+ let requestCounter = 0;
18
+ class NativeModbusTransport {
19
+ constructor(config = {}) {
20
+ this.socket = null;
21
+ this.buffer = '';
22
+ this.pending = new Map();
23
+ this.frameHandlers = [];
24
+ this.errorHandlers = [];
25
+ this.config = {
26
+ host: config.host ?? '127.0.0.1',
27
+ port: config.port ?? 15002,
28
+ connectTimeoutMs: config.connectTimeoutMs ?? 5000,
29
+ requestTimeoutMs: config.requestTimeoutMs ?? 10000,
30
+ };
31
+ }
32
+ async connect() {
33
+ const net = await import('net');
34
+ return new Promise((resolve, reject) => {
35
+ const timer = setTimeout(() => {
36
+ this.socket?.destroy();
37
+ reject(new Error(`NativeModbusTransport: connect timeout (${this.config.connectTimeoutMs}ms)`));
38
+ }, this.config.connectTimeoutMs);
39
+ this.socket = net.createConnection({ host: this.config.host, port: this.config.port }, () => {
40
+ clearTimeout(timer);
41
+ resolve();
42
+ });
43
+ this.socket.on('data', (chunk) => {
44
+ this.buffer += chunk.toString('utf-8');
45
+ const lines = this.buffer.split('\n');
46
+ this.buffer = lines.pop() ?? '';
47
+ for (const line of lines) {
48
+ if (!line.trim())
49
+ continue;
50
+ try {
51
+ const msg = JSON.parse(line);
52
+ if (msg.id && this.pending.has(msg.id)) {
53
+ const { resolve: res, reject: rej } = this.pending.get(msg.id);
54
+ this.pending.delete(msg.id);
55
+ if (msg.ok && msg.frame) {
56
+ res(hexToBytes(msg.frame));
57
+ }
58
+ else {
59
+ rej(new Error(msg.error ?? 'unknown error'));
60
+ }
61
+ }
62
+ }
63
+ catch {
64
+ // ignore parse errors on partial lines
65
+ }
66
+ }
67
+ });
68
+ this.socket.on('error', (err) => {
69
+ for (const handler of this.errorHandlers) {
70
+ try {
71
+ handler(err);
72
+ }
73
+ catch { }
74
+ }
75
+ });
76
+ this.socket.on('close', () => {
77
+ for (const [, pending] of this.pending) {
78
+ pending.reject(new Error('NativeModbusTransport: connection closed'));
79
+ }
80
+ this.pending.clear();
81
+ });
82
+ });
83
+ }
84
+ async disconnect() {
85
+ if (this.socket) {
86
+ this.socket.destroy();
87
+ this.socket = null;
88
+ }
89
+ }
90
+ async sendFrame(frame) {
91
+ if (!this.socket) {
92
+ throw new Error('NativeModbusTransport: not connected');
93
+ }
94
+ const id = `modbus-${++requestCounter}`;
95
+ const request = { id, frame: bytesToHex(frame) };
96
+ return new Promise((resolve, reject) => {
97
+ const timer = setTimeout(() => {
98
+ this.pending.delete(id);
99
+ reject(new Error(`NativeModbusTransport: request ${id} timed out (${this.config.requestTimeoutMs}ms)`));
100
+ }, this.config.requestTimeoutMs);
101
+ this.pending.set(id, {
102
+ resolve: (data) => { clearTimeout(timer); resolve(data); },
103
+ reject: (err) => { clearTimeout(timer); reject(err); },
104
+ });
105
+ this.socket.write(JSON.stringify(request) + '\n');
106
+ });
107
+ }
108
+ onFrame(handler) {
109
+ this.frameHandlers.push(handler);
110
+ return () => {
111
+ this.frameHandlers = this.frameHandlers.filter(h => h !== handler);
112
+ };
113
+ }
114
+ onError(handler) {
115
+ this.errorHandlers.push(handler);
116
+ return () => {
117
+ this.errorHandlers = this.errorHandlers.filter(h => h !== handler);
118
+ };
119
+ }
120
+ }
121
+ exports.NativeModbusTransport = NativeModbusTransport;
122
+ function bytesToHex(bytes) {
123
+ return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
124
+ }
125
+ function hexToBytes(hex) {
126
+ if (hex.length % 2 !== 0)
127
+ throw new Error('Invalid hex string');
128
+ const arr = new Uint8Array(hex.length / 2);
129
+ for (let i = 0; i < arr.length; i++) {
130
+ arr[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
131
+ }
132
+ return arr;
133
+ }
@@ -1,5 +1,7 @@
1
1
  /**
2
2
  * Modbus Sensor Bridge — maps Modbus register reads to Edge proof inputs.
3
+ *
4
+ * Uses RTU frame format (no MBAP header) to match the Go native binary.
3
5
  */
4
6
  import type { EdgeRuntime } from '@totemsdk/edge';
5
7
  import type { ModbusTransportPort } from './transport.js';
@@ -23,7 +25,6 @@ export interface ModbusSensorBridgeConfig {
23
25
  export interface ModbusSensorBridge {
24
26
  start(): Promise<void>;
25
27
  stop(): Promise<void>;
26
- /** Force a single poll cycle. */
27
28
  poll(): Promise<void>;
28
29
  }
29
30
  export declare function createModbusSensorBridge(config: ModbusSensorBridgeConfig): ModbusSensorBridge;
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Modbus Sensor Bridge — maps Modbus register reads to Edge proof inputs.
4
+ *
5
+ * Uses RTU frame format (no MBAP header) to match the Go native binary.
4
6
  */
5
7
  Object.defineProperty(exports, "__esModule", { value: true });
6
8
  exports.createModbusSensorBridge = createModbusSensorBridge;
@@ -10,14 +12,12 @@ function createModbusSensorBridge(config) {
10
12
  async function pollBinding(binding) {
11
13
  try {
12
14
  let values;
13
- if (binding.functionCode === 1) {
14
- const frame = buildReadFrame(binding.unitId, 1, binding.address, binding.count);
15
- const response = await config.transport.sendFrame(frame);
15
+ const frame = buildReadFrame(binding.unitId, binding.functionCode, binding.address, binding.count);
16
+ const response = await config.transport.sendFrame(frame);
17
+ if (binding.functionCode === 1 || binding.functionCode === 2) {
16
18
  values = parseCoils(response, binding.count);
17
19
  }
18
20
  else if (binding.functionCode === 3 || binding.functionCode === 4) {
19
- const frame = buildReadFrame(binding.unitId, binding.functionCode, binding.address, binding.count);
20
- const response = await config.transport.sendFrame(frame);
21
21
  values = parseRegisters(response, binding.count);
22
22
  }
23
23
  if (config.runtime.ports.proof) {
@@ -61,20 +61,22 @@ function createModbusSensorBridge(config) {
61
61
  },
62
62
  };
63
63
  }
64
+ // ── RTU frame builder (no MBAP header — matches Go binary) ────────────────
64
65
  function buildReadFrame(unitId, fc, address, count) {
65
- const buf = new Uint8Array(12);
66
- new DataView(buf.buffer).setUint16(0, 1, false); // transaction ID
67
- new DataView(buf.buffer).setUint16(4, 6, false); // length
68
- buf[6] = unitId;
69
- buf[7] = fc;
70
- new DataView(buf.buffer).setUint16(8, address, false);
71
- new DataView(buf.buffer).setUint16(10, count, false);
66
+ const buf = new Uint8Array(8);
67
+ buf[0] = unitId;
68
+ buf[1] = fc;
69
+ new DataView(buf.buffer).setUint16(2, address, false);
70
+ new DataView(buf.buffer).setUint16(4, count, false);
71
+ buf[6] = 0;
72
+ buf[7] = 0;
72
73
  return buf;
73
74
  }
75
+ // ── Response parsers (RTU format — no MBAP header) ────────────────────────
74
76
  function parseCoils(response, count) {
75
77
  const result = [];
76
78
  for (let i = 0; i < count; i++) {
77
- const byte = response[9 + Math.floor(i / 8)] ?? 0;
79
+ const byte = response[3 + Math.floor(i / 8)] ?? 0;
78
80
  result.push(((byte >> (i % 8)) & 1) === 1);
79
81
  }
80
82
  return result;
@@ -82,7 +84,7 @@ function parseCoils(response, count) {
82
84
  function parseRegisters(response, count) {
83
85
  const result = [];
84
86
  for (let i = 0; i < count; i++) {
85
- result.push(new DataView(response.buffer, response.byteOffset + 9 + i * 2, 2).getUint16(0, false));
87
+ result.push(new DataView(response.buffer, response.byteOffset + 3 + i * 2, 2).getUint16(0, false));
86
88
  }
87
89
  return result;
88
90
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@totemsdk/edge-modbus",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Edge runtime adapter for Modbus — PLCs, RTUs, industrial sensors over serial/TCP",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -11,15 +11,13 @@
11
11
  "import": "./dist/index.js"
12
12
  }
13
13
  },
14
- "scripts": {
15
- "build": "tsc",
16
- "prepare": "tsc",
17
- "clean": "rm -rf dist",
18
- "test": "jest --passWithNoTests"
19
- },
20
- "files": ["dist", "README.md", "LICENSE"],
14
+ "files": [
15
+ "dist",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
21
19
  "dependencies": {
22
- "@totemsdk/edge": "^0.1.3"
20
+ "@totemsdk/edge": "^1.0.0"
23
21
  },
24
22
  "devDependencies": {
25
23
  "@types/jest": "^30.0.0",
@@ -28,16 +26,36 @@
28
26
  "ts-jest": "^29.0.0",
29
27
  "typescript": "^7.0.2"
30
28
  },
31
- "engines": { "node": ">=18.0.0" },
32
- "publishConfig": { "access": "public" },
29
+ "engines": {
30
+ "node": ">=18.0.0"
31
+ },
32
+ "publishConfig": {
33
+ "access": "public"
34
+ },
33
35
  "license": "MIT",
34
36
  "author": "Totem SDK",
35
37
  "homepage": "https://totem.ing",
36
38
  "repository": {
37
39
  "type": "git",
38
- "url": "git+https://github.com/totem-sdk/totem-sdk.git",
39
- "directory": "packages/totem-sdk/packages/edge-modbus"
40
+ "url": "git+https://github.com/Totem-Edge/totem-sdk.git",
41
+ "directory": "packages/edge-modbus"
42
+ },
43
+ "keywords": [
44
+ "totem",
45
+ "totemsdk",
46
+ "minima",
47
+ "blockchain",
48
+ "edge",
49
+ "modbus",
50
+ "transport"
51
+ ],
52
+ "bugs": {
53
+ "url": "https://github.com/Totem-Edge/totem-sdk/issues"
40
54
  },
41
- "keywords": ["totem", "totemsdk", "minima", "blockchain", "edge", "modbus", "transport"],
42
- "bugs": { "url": "https://github.com/totem-sdk/totem-sdk/issues" }
43
- }
55
+ "scripts": {
56
+ "build": "tsc",
57
+ "build:go": "cd go && go build -o ../bin/edge-modbus .",
58
+ "clean": "rm -rf dist bin",
59
+ "test": "jest"
60
+ }
61
+ }