secs4js 0.1.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.
Files changed (129) hide show
  1. package/LICENSE.md +20 -0
  2. package/README.md +442 -0
  3. package/lib/core/AbstractSecsCommunicator.d.ts +76 -0
  4. package/lib/core/AbstractSecsCommunicator.d.ts.map +1 -0
  5. package/lib/core/AbstractSecsCommunicator.js +85 -0
  6. package/lib/core/AbstractSecsCommunicator.js.map +1 -0
  7. package/lib/core/AbstractSecsMessage.d.ts +36 -0
  8. package/lib/core/AbstractSecsMessage.d.ts.map +1 -0
  9. package/lib/core/AbstractSecsMessage.js +66 -0
  10. package/lib/core/AbstractSecsMessage.js.map +1 -0
  11. package/lib/core/enums/HsmsSsControlType.d.ts +59 -0
  12. package/lib/core/enums/HsmsSsControlType.d.ts.map +1 -0
  13. package/lib/core/enums/HsmsSsControlType.js +105 -0
  14. package/lib/core/enums/HsmsSsControlType.js.map +1 -0
  15. package/lib/core/enums/RejectReason.d.ts +11 -0
  16. package/lib/core/enums/RejectReason.d.ts.map +1 -0
  17. package/lib/core/enums/RejectReason.js +13 -0
  18. package/lib/core/enums/RejectReason.js.map +1 -0
  19. package/lib/core/enums/SecsItemType.d.ts +33 -0
  20. package/lib/core/enums/SecsItemType.d.ts.map +1 -0
  21. package/lib/core/enums/SecsItemType.js +22 -0
  22. package/lib/core/enums/SecsItemType.js.map +1 -0
  23. package/lib/core/enums/SelectStatus.d.ts +11 -0
  24. package/lib/core/enums/SelectStatus.d.ts.map +1 -0
  25. package/lib/core/enums/SelectStatus.js +13 -0
  26. package/lib/core/enums/SelectStatus.js.map +1 -0
  27. package/lib/core/secs2item/AbstractSecs2Item.d.ts +34 -0
  28. package/lib/core/secs2item/AbstractSecs2Item.d.ts.map +1 -0
  29. package/lib/core/secs2item/AbstractSecs2Item.js +59 -0
  30. package/lib/core/secs2item/AbstractSecs2Item.js.map +1 -0
  31. package/lib/core/secs2item/Secs2ItemAscii.d.ts +18 -0
  32. package/lib/core/secs2item/Secs2ItemAscii.d.ts.map +1 -0
  33. package/lib/core/secs2item/Secs2ItemAscii.js +27 -0
  34. package/lib/core/secs2item/Secs2ItemAscii.js.map +1 -0
  35. package/lib/core/secs2item/Secs2ItemBinary.d.ts +11 -0
  36. package/lib/core/secs2item/Secs2ItemBinary.d.ts.map +1 -0
  37. package/lib/core/secs2item/Secs2ItemBinary.js +22 -0
  38. package/lib/core/secs2item/Secs2ItemBinary.js.map +1 -0
  39. package/lib/core/secs2item/Secs2ItemBoolean.d.ts +12 -0
  40. package/lib/core/secs2item/Secs2ItemBoolean.d.ts.map +1 -0
  41. package/lib/core/secs2item/Secs2ItemBoolean.js +27 -0
  42. package/lib/core/secs2item/Secs2ItemBoolean.js.map +1 -0
  43. package/lib/core/secs2item/Secs2ItemFactory.d.ts +27 -0
  44. package/lib/core/secs2item/Secs2ItemFactory.d.ts.map +1 -0
  45. package/lib/core/secs2item/Secs2ItemFactory.js +56 -0
  46. package/lib/core/secs2item/Secs2ItemFactory.js.map +1 -0
  47. package/lib/core/secs2item/Secs2ItemList.d.ts +11 -0
  48. package/lib/core/secs2item/Secs2ItemList.d.ts.map +1 -0
  49. package/lib/core/secs2item/Secs2ItemList.js +26 -0
  50. package/lib/core/secs2item/Secs2ItemList.js.map +1 -0
  51. package/lib/core/secs2item/Secs2ItemNumeric.d.ts +14 -0
  52. package/lib/core/secs2item/Secs2ItemNumeric.d.ts.map +1 -0
  53. package/lib/core/secs2item/Secs2ItemNumeric.js +128 -0
  54. package/lib/core/secs2item/Secs2ItemNumeric.js.map +1 -0
  55. package/lib/core/secs2item/Secs2ItemParser.d.ts +12 -0
  56. package/lib/core/secs2item/Secs2ItemParser.d.ts.map +1 -0
  57. package/lib/core/secs2item/Secs2ItemParser.js +74 -0
  58. package/lib/core/secs2item/Secs2ItemParser.js.map +1 -0
  59. package/lib/gem/Clock.d.ts +21 -0
  60. package/lib/gem/Clock.d.ts.map +1 -0
  61. package/lib/gem/Clock.js +65 -0
  62. package/lib/gem/Clock.js.map +1 -0
  63. package/lib/gem/Gem.d.ts +55 -0
  64. package/lib/gem/Gem.d.ts.map +1 -0
  65. package/lib/gem/Gem.js +137 -0
  66. package/lib/gem/Gem.js.map +1 -0
  67. package/lib/helper/Secs2ItemHelper.d.ts +96 -0
  68. package/lib/helper/Secs2ItemHelper.d.ts.map +1 -0
  69. package/lib/helper/Secs2ItemHelper.js +135 -0
  70. package/lib/helper/Secs2ItemHelper.js.map +1 -0
  71. package/lib/hsms/HsmsActiveCommunicator.d.ts +29 -0
  72. package/lib/hsms/HsmsActiveCommunicator.d.ts.map +1 -0
  73. package/lib/hsms/HsmsActiveCommunicator.js +123 -0
  74. package/lib/hsms/HsmsActiveCommunicator.js.map +1 -0
  75. package/lib/hsms/HsmsCommunicator.d.ts +70 -0
  76. package/lib/hsms/HsmsCommunicator.d.ts.map +1 -0
  77. package/lib/hsms/HsmsCommunicator.js +322 -0
  78. package/lib/hsms/HsmsCommunicator.js.map +1 -0
  79. package/lib/hsms/HsmsMessage.d.ts +92 -0
  80. package/lib/hsms/HsmsMessage.d.ts.map +1 -0
  81. package/lib/hsms/HsmsMessage.js +163 -0
  82. package/lib/hsms/HsmsMessage.js.map +1 -0
  83. package/lib/hsms/HsmsPassiveCommunicator.d.ts +48 -0
  84. package/lib/hsms/HsmsPassiveCommunicator.d.ts.map +1 -0
  85. package/lib/hsms/HsmsPassiveCommunicator.js +304 -0
  86. package/lib/hsms/HsmsPassiveCommunicator.js.map +1 -0
  87. package/lib/hsms/enums/HsmsControlType.d.ts +15 -0
  88. package/lib/hsms/enums/HsmsControlType.d.ts.map +1 -0
  89. package/lib/hsms/enums/HsmsControlType.js +17 -0
  90. package/lib/hsms/enums/HsmsControlType.js.map +1 -0
  91. package/lib/hsms/enums/RejectReason.d.ts +11 -0
  92. package/lib/hsms/enums/RejectReason.d.ts.map +1 -0
  93. package/lib/hsms/enums/RejectReason.js +13 -0
  94. package/lib/hsms/enums/RejectReason.js.map +1 -0
  95. package/lib/hsms/enums/SelectStatus.d.ts +11 -0
  96. package/lib/hsms/enums/SelectStatus.d.ts.map +1 -0
  97. package/lib/hsms/enums/SelectStatus.js +13 -0
  98. package/lib/hsms/enums/SelectStatus.js.map +1 -0
  99. package/lib/index.d.ts +28 -0
  100. package/lib/index.js +29 -0
  101. package/lib/secs1/Secs1Communicator.d.ts +51 -0
  102. package/lib/secs1/Secs1Communicator.d.ts.map +1 -0
  103. package/lib/secs1/Secs1Communicator.js +342 -0
  104. package/lib/secs1/Secs1Communicator.js.map +1 -0
  105. package/lib/secs1/Secs1Message.d.ts +21 -0
  106. package/lib/secs1/Secs1Message.d.ts.map +1 -0
  107. package/lib/secs1/Secs1Message.js +77 -0
  108. package/lib/secs1/Secs1Message.js.map +1 -0
  109. package/lib/secs1/Secs1MessageBlock.d.ts +23 -0
  110. package/lib/secs1/Secs1MessageBlock.d.ts.map +1 -0
  111. package/lib/secs1/Secs1MessageBlock.js +86 -0
  112. package/lib/secs1/Secs1MessageBlock.js.map +1 -0
  113. package/lib/secs1/Secs1OnTcpIpActiveCommunicator.d.ts +23 -0
  114. package/lib/secs1/Secs1OnTcpIpActiveCommunicator.d.ts.map +1 -0
  115. package/lib/secs1/Secs1OnTcpIpActiveCommunicator.js +82 -0
  116. package/lib/secs1/Secs1OnTcpIpActiveCommunicator.js.map +1 -0
  117. package/lib/secs1/Secs1OnTcpIpPassiveCommunicator.d.ts +19 -0
  118. package/lib/secs1/Secs1OnTcpIpPassiveCommunicator.d.ts.map +1 -0
  119. package/lib/secs1/Secs1OnTcpIpPassiveCommunicator.js +49 -0
  120. package/lib/secs1/Secs1OnTcpIpPassiveCommunicator.js.map +1 -0
  121. package/lib/secs1/Secs1SerialCommunicator.d.ts +18 -0
  122. package/lib/secs1/Secs1SerialCommunicator.d.ts.map +1 -0
  123. package/lib/secs1/Secs1SerialCommunicator.js +59 -0
  124. package/lib/secs1/Secs1SerialCommunicator.js.map +1 -0
  125. package/lib/sml/SmlParser.d.ts +27 -0
  126. package/lib/sml/SmlParser.d.ts.map +1 -0
  127. package/lib/sml/SmlParser.js +184 -0
  128. package/lib/sml/SmlParser.js.map +1 -0
  129. package/package.json +53 -0
package/LICENSE.md ADDED
@@ -0,0 +1,20 @@
1
+ # MIT License
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ 'Software'), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,442 @@
1
+ <h1 align="center">Secs4js</h1>
2
+
3
+ <p align="center">A simple, efficient, and user-friendly SECS/GEM protocol library implemented in TypeScript.</p>
4
+
5
+ ## Introduction
6
+
7
+ This project is a TypeScript implementation of the SECS/GEM protocol, inspired by [pysemisecs](https://github.com/kenta-shimizu/pysemisecs).
8
+
9
+ A special thanks to the author **kenta-shimizu** for their open-source contribution.
10
+
11
+ Secs4js is a simple, efficient, and user-friendly SECS/GEM protocol library implemented in TypeScript. It provides a straightforward way to communicate with SECS/GEM devices, enabling you to easily read and write data using the SECS/GEM protocol.
12
+
13
+ ## Supported Features
14
+
15
+ - SECS-I (SEMI-E4)
16
+ - SECS-I Virtual Serial Port (SECS-I on TCP/IP)
17
+ - SECS-II (SEMI-E5)
18
+ - GEM (SEMI-E30)
19
+ - HSMS-SS (SEMI-E37.1)
20
+ - **No HSMS-GS (SEMI-E37.2)**
21
+
22
+ ## Installation
23
+
24
+ ```shell
25
+ npm i secs4js
26
+
27
+ pnpm add secs4js
28
+
29
+ yarn add secs4js
30
+
31
+ bun add secs4js
32
+ ```
33
+
34
+ ## Getting Started from Source
35
+
36
+ If you want to run some examples, they can be found in the `examples` directory.
37
+
38
+ Run the following commands to start these examples:
39
+
40
+ ```shell
41
+ pnpm dlx tsx examples/gem_example.ts
42
+
43
+ # ...
44
+ pnpm dlx tsx examples/<example_file_name>.ts
45
+ ```
46
+
47
+ ## Usage
48
+
49
+ ### 1. Creating SECS-II Messages
50
+
51
+ I provide a concise, clear, and efficient way to create SECS-II message types. You can use the following code to import the required items:
52
+
53
+ ```ts
54
+ import { B, U1, U2, U4, U8, I1, I2, I4, I8, F4, F8, A, L } from "secs4js";
55
+ ```
56
+
57
+ Using these items, you can easily create SECS-II message types. For example, to create a message containing L, A, and U1 items, you can use the following code:
58
+
59
+ ```ts
60
+ import { L, A, U1, SecsMessage } from "secs4js";
61
+
62
+ const body: AbstractSecs2Item = L(A("Hello, SECS/GEM!"), U1(123));
63
+ ```
64
+
65
+ Doesn't this highly resemble SML text syntax?
66
+
67
+ All SECS-II messages are derived from the `AbstractSecs2Item` class, so you can use it to declare any SECS-II message of unknown type.
68
+
69
+ If you don't like this approach, you can also use SML text syntax or the factory methods we provide to create SECS-II messages.
70
+
71
+ Factory methods:
72
+
73
+ ```ts
74
+ import { Secs2ItemFactory } from "secs4js";
75
+
76
+ // Create a message containing L, A, and U1 items
77
+ const newMsg = Secs2ItemFactory.createListItem(
78
+ Secs2ItemFactory.createAsciiItem("Hello World"),
79
+ Secs2ItemFactory.createU1Item(123),
80
+ );
81
+ ```
82
+
83
+ SML Conversion Support:
84
+
85
+ You can use the `toSml` method of the `AbstractSecs2Item` class to convert SECS-II messages to SML text. For example:
86
+
87
+ ```ts
88
+ console.log(newMsg.toSml());
89
+
90
+ // Output:
91
+ // <L
92
+ // <A "Hello World">
93
+ // <U1 123>
94
+ // >.
95
+ ```
96
+
97
+ ### 2. Creating SECS Messages
98
+
99
+ We provide two ways to create SECS-II messages:
100
+
101
+ 1. Use the `SecsMessage` class to create SECS-II messages.
102
+ 2. Create SECS-II messages by parsing SML syntax text. You can use the `SmlParser` static class to parse SML text and create corresponding SECS-II messages.
103
+
104
+ #### new SecsMessage(...)
105
+
106
+ > You can use the `SecsMessage` class to create SECS-II messages. The class constructor accepts the following parameters:
107
+ >
108
+ > - `stream`: Stream number, one byte, range 0-255.
109
+ > - `function`: Function number, one byte, range 0-255.
110
+ > - `wBit`: W-bit, a boolean indicating whether to enable W-bit (i.e., whether a reply is required).
111
+ > - `body`: SECS-II message body, an `AbstractSecs2Item` instance.
112
+ > - We will automatically generate the message's `length` and `systemBytes`, so you don't need to manage them manually.
113
+
114
+ ```ts
115
+ import { SecsMessage } from "secs4js";
116
+
117
+ const newMsg = new SecsMessage(1, 13, true, L(L(A("Hello World"), U1(123))));
118
+ ```
119
+
120
+ #### SmlParser
121
+
122
+ ```ts
123
+ import { SmlParser } from "secs4js";
124
+
125
+ // Complete SML text
126
+ const sml = `
127
+ S1F13 W
128
+ <L
129
+ <B 0x20>
130
+ <A "Hello World">
131
+ >.
132
+ `;
133
+
134
+ // SML text containing only the message body
135
+ const smlBody = `
136
+ <L
137
+ <B 0x20>
138
+ <A "Hello World">
139
+ >.
140
+ `;
141
+
142
+ // Parse complete SML text into a SecsMessage instance using the parse method
143
+ const parsedMessage = SmlParser.parse(sml);
144
+ const firstBodyItem =
145
+ parsedMessage.body instanceof Secs2ItemList
146
+ ? parsedMessage.body.value[0]
147
+ : null;
148
+ const bytes =
149
+ firstBodyItem instanceof Secs2ItemBinary ? firstBodyItem.value : null;
150
+ console.log(
151
+ parsedMessage.stream,
152
+ parsedMessage.func,
153
+ parsedMessage.wBit,
154
+ bytes,
155
+ );
156
+
157
+ // Parse SML text containing only the message body into an AbstractSecs2Item instance using the parseBody method
158
+ const parsedBody = SmlParser.parseBody(smlBody);
159
+ console.log(parsedBody?.toSml());
160
+ ```
161
+
162
+ ## HSMS-SS
163
+
164
+ For HSMS-SS protocol support, you can act as the passive end (Equipment) or the active end (HOST/EAP).
165
+
166
+ ### Active
167
+
168
+ Quick start:
169
+
170
+ ```ts
171
+ const active = new HsmsActiveCommunicator({
172
+ ip: "127.0.0.1",
173
+ port: 5000,
174
+ deviceId: 10,
175
+ isEquip: false,
176
+ // If you need to customize the timeout values, you can add additional parameters
177
+ // timeoutT1: 10,
178
+ // ...
179
+ });
180
+
181
+ active.on("connected", () => console.log("Active TCP Connected"));
182
+ active.on("disconnected", () => console.log("Active Disconnected"));
183
+ active.on("selected", () => console.log("Active Selected (HSMS Ready)"));
184
+
185
+ await active.open();
186
+ console.log("Active opened");
187
+
188
+ // Active will automatically send SelectReq and start heartbeat
189
+
190
+ await active.untilConnected(); // Wait for Select success
191
+
192
+ // When you need to receive and process messages, you can listen for the "message" event
193
+ active.on("message", (msg: SecsMessage) => {
194
+ void (async () => {
195
+ console.log(`Active received: ${msg.toSml()}`);
196
+ if (msg.stream === 1 && msg.func === 1) {
197
+ await active.reply(msg, 1, 2, L(A("MDLN-A"), A("SOFTREV-1")));
198
+ }
199
+ if (msg.stream === 1 && msg.func === 13) {
200
+ await active.reply(msg, 1, 14, L(A("ACK")));
201
+ }
202
+ })();
203
+ });
204
+
205
+ const reply = await active.send(1, 1, true);
206
+ console.log(`Active received reply: ${reply?.toSml()}`);
207
+
208
+ // Interaction results with the simulator
209
+ // Our reply message:
210
+ // 2025-12-30 01:26:44.866:onReceivedEvent[TOOL] DeviceID=[10] SB=[6110]
211
+ // S1F2
212
+ // <L[2/1]
213
+ // <A[6/1] "MDLN-A">
214
+ // <A[9/1] "SOFTREV-1">
215
+ // >.
216
+
217
+ // Message actively sent by the simulator:
218
+ // 2025-12-30 01:26:44.864:OnSent[TOOL] DeviceID=[1] SB=[6110]
219
+
220
+ // S1F1 W.
221
+ // 2025-12-30 01:26:44.864:Send the Message successfully.
222
+
223
+ // Message replied by the simulator:
224
+ // 2025-12-30 01:26:40.449:OnSent[TOOL] DeviceID=[10] SB=[2]
225
+ // S1F2
226
+ // <L[0/1]>.
227
+
228
+ // Message we actively sent:
229
+ // 2025-12-30 01:26:40.445:Do not find Tool in QutoReply List by Tool[TOOL] SFName=[S1F1]
230
+ // 2025-12-30 01:26:40.444:onReceivedEvent[TOOL] DeviceID=[10] SB=[2]
231
+ // S1F1 W.
232
+ ```
233
+
234
+ ### Passive
235
+
236
+ ```ts
237
+ import {
238
+ HsmsPassiveCommunicator,
239
+ SecsMessage,
240
+ CommAck,
241
+ OnlAck,
242
+ Gem,
243
+ } from "secs4js";
244
+
245
+ // 1. Set up Equipment side (Passive)
246
+ const equipComm = new HsmsPassiveCommunicator({
247
+ ip: "127.0.0.1",
248
+ port: 5000,
249
+ deviceId: 1,
250
+ isEquip: true,
251
+ name: "Equipment",
252
+ });
253
+
254
+ // Use the GEM helper class (optional)
255
+ const equipGem = new Gem(equipComm);
256
+ equipGem.mdln = "MyEquip";
257
+ equipGem.softrev = "1.0.0";
258
+
259
+ // Handle received messages
260
+ equipComm.on("message", (msg: SecsMessage) => {
261
+ void (async () => {
262
+ try {
263
+ // S1F13: Establish Communications Request
264
+ if (msg.stream === 1 && msg.func === 13) {
265
+ console.log("[Equip] Received S1F13, replying S1F14...");
266
+ await equipGem.s1f14(msg, CommAck.OK);
267
+ }
268
+ // S1F17: Request ON-LINE
269
+ else if (msg.stream === 1 && msg.func === 17) {
270
+ console.log("[Equip] Received S1F17, replying S1F18...");
271
+ await equipGem.s1f18(msg, OnlAck.OK);
272
+ }
273
+ // S2F17: Date and Time Request
274
+ else if (msg.stream === 2 && msg.func === 17) {
275
+ console.log("[Equip] Received S2F17, replying S2F18...");
276
+ await equipGem.s2f18Now(msg);
277
+ } else {
278
+ console.log(
279
+ `[Equip] Received unhandled message S${msg.stream}F${msg.func}`,
280
+ );
281
+ }
282
+ } catch (err) {
283
+ console.error("[Equip] Error handling message:", err);
284
+ }
285
+ })();
286
+ });
287
+
288
+ await equipComm.open();
289
+ console.log("Passive opened and listening");
290
+ ```
291
+
292
+ ## SECS-I Serial
293
+
294
+ Supports SECS-I communication via serial port.
295
+
296
+ **Note**:
297
+
298
+ - Serial port communication needs to be tested on devices that support the SECS-I protocol.
299
+ - Ensure the serial port path and baud rate match your device configuration.
300
+ - If you want to test locally first, we recommend using a **virtual serial port tool** to simulate serial port communication.
301
+
302
+ ### Active
303
+
304
+ ```ts
305
+ import { A, L, Secs1SerialCommunicator, SecsMessage } from "secs4js";
306
+
307
+ async function SerialActive() {
308
+ const active = new Secs1SerialCommunicator({
309
+ path: "COM5", // Serial port path
310
+ baudRate: 9600, // Baud rate
311
+ deviceId: 10,
312
+ isEquip: false, // Whether it is equipment
313
+ });
314
+
315
+ active.on("message", (msg: SecsMessage) => {
316
+ void (async () => {
317
+ console.log(`Active received: ${msg.toSml()}`);
318
+ if (msg.stream === 1 && msg.func === 1) {
319
+ await active.reply(msg, 1, 2, L(A("MDLN-A"), A("SOFTREV-1")));
320
+ }
321
+ })();
322
+ });
323
+
324
+ active.on("connected", () => {
325
+ console.log("Active connected");
326
+ });
327
+
328
+ await active.open();
329
+ console.log("Active opened");
330
+ }
331
+
332
+ SerialActive().catch((err) => console.error(err));
333
+
334
+ // Communication results with the simulator
335
+ // Our reply message:
336
+ // 2025-12-30 01:35:40.187:onReceivedEvent[SERIAL_EQP] DeviceID=[10] SB=[5985]
337
+ // S1F2
338
+ // <L[2/1]
339
+ // <A[6/1] "MDLN-A">
340
+ // <A[9/1] "SOFTREV-1">
341
+ // >.
342
+
343
+ // Message actively sent by the simulator:
344
+ // 2025-12-30 01:35:40.155:OnSent[SERIAL_EQP] DeviceID=[1] SB=[5985]
345
+
346
+ // S1F1 W.
347
+ // 2025-12-30 01:35:40.095:Send the Message successfully.
348
+ ```
349
+
350
+ ### Passive
351
+
352
+ ```ts
353
+ import { Secs1SerialCommunicator, SecsMessage, L, A } from "secs4js";
354
+
355
+ async function SerialPassive() {
356
+ const passive = new Secs1SerialCommunicator({
357
+ path: "COM5",
358
+ baudRate: 9600,
359
+ deviceId: 10,
360
+ isEquip: true,
361
+ });
362
+
363
+ passive.on("message", (msg: SecsMessage) => {
364
+ void (async () => {
365
+ if (msg.stream === 1 && msg.func === 1) {
366
+ await passive.reply(msg, 1, 2, L(A("MDLN-A"), A("SOFTREV-1")));
367
+ }
368
+ console.log(`Passive received: ${msg.toSml()}`);
369
+ })();
370
+ });
371
+
372
+ await passive.open();
373
+ console.log("Passive opened");
374
+ }
375
+
376
+ SerialPassive().catch((err) => console.error(err));
377
+ ```
378
+
379
+ ## SECS-I On TCP/IP
380
+
381
+ Supports SECS-I serial communication via TCP/IP (usually used for testing or connecting through a terminal server).
382
+
383
+ ### Active
384
+
385
+ ```ts
386
+ import { Secs1OnTcpIpActiveCommunicator, SecsMessage, L, A } from "secs4js";
387
+
388
+ async function TcpActive() {
389
+ const active = new Secs1OnTcpIpActiveCommunicator({
390
+ ip: "127.0.0.1",
391
+ port: 5000,
392
+ deviceId: 10,
393
+ isEquip: false,
394
+ });
395
+
396
+ active.on("message", (msg: SecsMessage) => {
397
+ void (async () => {
398
+ console.log(`Active received: ${msg.toSml()}`);
399
+ // Handle message...
400
+ })();
401
+ });
402
+
403
+ active.on("connected", () => {
404
+ console.log("Active connected");
405
+ });
406
+
407
+ await active.open();
408
+ }
409
+ ```
410
+
411
+ ### Passive
412
+
413
+ ```ts
414
+ import { Secs1OnTcpIpPassiveCommunicator, SecsMessage, L, A } from "secs4js";
415
+
416
+ async function TcpPassive() {
417
+ const passive = new Secs1OnTcpIpPassiveCommunicator({
418
+ ip: "0.0.0.0",
419
+ port: 5000,
420
+ deviceId: 10,
421
+ isEquip: true,
422
+ });
423
+
424
+ passive.on("message", (msg: SecsMessage) => {
425
+ void (async () => {
426
+ console.log(`Passive received: ${msg.toSml()}`);
427
+ // Process message and reply...
428
+ })();
429
+ });
430
+
431
+ await passive.open();
432
+ console.log("Passive server started");
433
+ }
434
+ ```
435
+
436
+ ## Development
437
+
438
+ If you are interested in this project, welcome to contribute your code!
439
+
440
+ Thank you for your contribution! 💖
441
+
442
+ > 💝 This project was generated using [`create-typescript-app`](https://github.com/JoshuaKGoldberg/create-typescript-app) and the [Bingo framework](https://create.bingo).
@@ -0,0 +1,76 @@
1
+ import { AbstractSecs2Item } from "./secs2item/AbstractSecs2Item.js";
2
+ import { SecsMessage } from "./AbstractSecsMessage.js";
3
+ import { EventEmitter } from "events";
4
+
5
+ //#region src/core/AbstractSecsCommunicator.d.ts
6
+
7
+ /**
8
+ * @param message The message received.
9
+ * @param error The error occurred.
10
+ * @param connected The connection is established.
11
+ * @param disconnected The connection is closed.
12
+ */
13
+ interface SecsCommunicatorEvents {
14
+ message: [SecsMessage];
15
+ error: [Error];
16
+ connected: [];
17
+ disconnected: [];
18
+ }
19
+ /**
20
+ * @param deviceId The device ID.
21
+ * @param isEquip Whether the device is an equip.
22
+ * @param name The name of the connection.
23
+ * @param timeoutT1 Only SECS-I supports this parameter, ENQ retransmission interval.
24
+ * @param timeoutT2 Only SECS-I supports this parameter, ENQ wait-for-response timeout.
25
+ * @param timeoutT3 Support SECS-I and SECS-II, W-Bit timeout.
26
+ * @param timeoutT4 Only SECS-I supports this parameter, data block retransmission interval.
27
+ * @param timeoutT5 Support SECS-I and SECS-II, establishment of communication session timeout.
28
+ * @param timeoutT6 Only HSMS supports this parameter, reply control message timeout.
29
+ * @param timeoutT7 Only HSMS supports this parameter, create connection timeout.
30
+ * @param timeoutT8 Only HSMS supports this parameter, the maximum time interval between message bytes when receiving a message
31
+ */
32
+ interface SecsCommunicatorConfig {
33
+ deviceId: number;
34
+ isEquip: boolean;
35
+ name?: string;
36
+ timeoutT1?: number;
37
+ timeoutT2?: number;
38
+ timeoutT3?: number;
39
+ timeoutT4?: number;
40
+ timeoutT5?: number;
41
+ timeoutT6?: number;
42
+ timeoutT7?: number;
43
+ timeoutT8?: number;
44
+ }
45
+ declare abstract class AbstractSecsCommunicator<Events extends Record<keyof Events, unknown[]> & SecsCommunicatorEvents = SecsCommunicatorEvents> extends EventEmitter {
46
+ readonly deviceId: number;
47
+ readonly isEquip: boolean;
48
+ readonly name: string;
49
+ timeoutT1: number;
50
+ timeoutT2: number;
51
+ timeoutT3: number;
52
+ timeoutT4: number;
53
+ timeoutT5: number;
54
+ timeoutT6: number;
55
+ timeoutT7: number;
56
+ timeoutT8: number;
57
+ protected _systemBytesCounter: number;
58
+ protected _transactions: Map<number, {
59
+ resolve: (msg: SecsMessage) => void;
60
+ reject: (err: Error) => void;
61
+ timer: NodeJS.Timeout;
62
+ }>;
63
+ constructor(config: SecsCommunicatorConfig);
64
+ abstract open(): Promise<void>;
65
+ abstract close(): Promise<void>;
66
+ protected emitInternal(eventName: string | symbol, ...args: unknown[]): boolean;
67
+ protected abstract sendBuffer(buffer: Buffer): Promise<void>;
68
+ protected abstract createMessage(stream: number, func: number, wBit: boolean, body: AbstractSecs2Item | null, systemBytes: number): SecsMessage;
69
+ send(stream: number, func: number, wBit: boolean, body?: AbstractSecs2Item | null): Promise<SecsMessage | null>;
70
+ reply(primaryMsg: SecsMessage, stream: number, func: number, body?: AbstractSecs2Item | null): Promise<void>;
71
+ protected getNextSystemBytes(): number;
72
+ protected handleMessage(msg: SecsMessage): void;
73
+ }
74
+ //#endregion
75
+ export { AbstractSecsCommunicator, SecsCommunicatorConfig, SecsCommunicatorEvents };
76
+ //# sourceMappingURL=AbstractSecsCommunicator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractSecsCommunicator.d.ts","names":[],"sources":["../../src/core/AbstractSecsCommunicator.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAUA;AAoBA;AAcA;;AACgB,UAnCC,sBAAA,CAmCD;EAAkC,OAAA,EAAA,CAlCvC,WAkCuC,CAAA;EAChD,KAAA,EAAA,CAlCO,KAkCP,CAAA;EAmBgB,SAAA,EAAA,EAAA;EACD,YAAA,EAAA,EAAA;;;;;;;;;;;;;;;AAwFb,UA5Ha,sBAAA,CA4Hb;EAkB0B,QAAA,EAAA,MAAA;EA7HpB,OAAA,EAAA,OAAA;EAAY,IAAA,CAAA,EAAA,MAAA;;;;;;;;;;uBAHA,wCACN,aAAa,qBAAqB,yBAChD,gCACQ,YAAA;;;;;;;;;;;;;2BAec;mBAGN;kBACD;WACP,MAAA,CAAO;;sBAII;mBAeH;oBACC;;wCAgBoB,SAAS;sFAMxC,gDAEJ;2DAMI,2BACJ,QAAQ;oBAgCE,kDAGN,2BACJ;;+BAkB0B"}
@@ -0,0 +1,85 @@
1
+ import { EventEmitter } from "events";
2
+
3
+ //#region src/core/AbstractSecsCommunicator.ts
4
+ var AbstractSecsCommunicator = class extends EventEmitter {
5
+ deviceId;
6
+ isEquip;
7
+ name;
8
+ timeoutT1 = 1;
9
+ timeoutT2 = 15;
10
+ timeoutT3 = 45;
11
+ timeoutT4 = 45;
12
+ timeoutT5 = 10;
13
+ timeoutT6 = 5;
14
+ timeoutT7 = 10;
15
+ timeoutT8 = 5;
16
+ _systemBytesCounter = 0;
17
+ _transactions = /* @__PURE__ */ new Map();
18
+ constructor(config) {
19
+ super();
20
+ this.deviceId = config.deviceId;
21
+ this.isEquip = config.isEquip;
22
+ this.name = config.name ?? "SecsCommunicator";
23
+ if (config.timeoutT1 !== void 0) this.timeoutT1 = config.timeoutT1;
24
+ if (config.timeoutT2 !== void 0) this.timeoutT2 = config.timeoutT2;
25
+ if (config.timeoutT3 !== void 0) this.timeoutT3 = config.timeoutT3;
26
+ if (config.timeoutT4 !== void 0) this.timeoutT4 = config.timeoutT4;
27
+ if (config.timeoutT5 !== void 0) this.timeoutT5 = config.timeoutT5;
28
+ if (config.timeoutT6 !== void 0) this.timeoutT6 = config.timeoutT6;
29
+ if (config.timeoutT7 !== void 0) this.timeoutT7 = config.timeoutT7;
30
+ if (config.timeoutT8 !== void 0) this.timeoutT8 = config.timeoutT8;
31
+ }
32
+ emitInternal(eventName, ...args) {
33
+ return super.emit.call(this, eventName, ...args);
34
+ }
35
+ async send(stream, func, wBit, body = null) {
36
+ const systemBytes = this.getNextSystemBytes();
37
+ const msg = this.createMessage(stream, func, wBit, body, systemBytes);
38
+ if (wBit) return new Promise((resolve, reject) => {
39
+ const timer = setTimeout(() => {
40
+ if (this._transactions.has(systemBytes)) {
41
+ this._transactions.delete(systemBytes);
42
+ reject(/* @__PURE__ */ new Error(`T3 Timeout waiting for reply to S${String(stream)}F${String(func)} [SysBytes=${String(systemBytes)}]`));
43
+ }
44
+ }, this.timeoutT3 * 1e3);
45
+ this._transactions.set(systemBytes, {
46
+ resolve,
47
+ reject,
48
+ timer
49
+ });
50
+ this.sendBuffer(msg.toBuffer()).catch((err) => {
51
+ clearTimeout(timer);
52
+ this._transactions.delete(systemBytes);
53
+ reject(err instanceof Error ? err : new Error(String(err)));
54
+ });
55
+ });
56
+ else {
57
+ await this.sendBuffer(msg.toBuffer());
58
+ return null;
59
+ }
60
+ }
61
+ async reply(primaryMsg, stream, func, body = null) {
62
+ const msg = this.createMessage(stream, func, false, body, primaryMsg.systemBytes);
63
+ console.log("Reply Buffer:", msg.toBuffer());
64
+ console.log(`Reply: ${msg.toSml()}`);
65
+ await this.sendBuffer(msg.toBuffer());
66
+ }
67
+ getNextSystemBytes() {
68
+ this._systemBytesCounter = this._systemBytesCounter + 1 >>> 0;
69
+ return this._systemBytesCounter;
70
+ }
71
+ handleMessage(msg) {
72
+ const tx = this._transactions.get(msg.systemBytes);
73
+ if (tx) {
74
+ clearTimeout(tx.timer);
75
+ this._transactions.delete(msg.systemBytes);
76
+ tx.resolve(msg);
77
+ return;
78
+ }
79
+ this.emitInternal("message", msg);
80
+ }
81
+ };
82
+
83
+ //#endregion
84
+ export { AbstractSecsCommunicator };
85
+ //# sourceMappingURL=AbstractSecsCommunicator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractSecsCommunicator.js","names":[],"sources":["../../src/core/AbstractSecsCommunicator.ts"],"sourcesContent":["import { EventEmitter } from \"events\";\nimport { SecsMessage } from \"./AbstractSecsMessage.js\";\nimport { AbstractSecs2Item } from \"./secs2item/AbstractSecs2Item.js\";\n\n/**\n * @param message The message received.\n * @param error The error occurred.\n * @param connected The connection is established.\n * @param disconnected The connection is closed.\n */\nexport interface SecsCommunicatorEvents {\n\tmessage: [SecsMessage];\n\terror: [Error];\n\tconnected: [];\n\tdisconnected: [];\n}\n\n/**\n * @param deviceId The device ID.\n * @param isEquip Whether the device is an equip.\n * @param name The name of the connection.\n * @param timeoutT1 Only SECS-I supports this parameter, ENQ retransmission interval.\n * @param timeoutT2 Only SECS-I supports this parameter, ENQ wait-for-response timeout.\n * @param timeoutT3 Support SECS-I and SECS-II, W-Bit timeout.\n * @param timeoutT4 Only SECS-I supports this parameter, data block retransmission interval.\n * @param timeoutT5 Support SECS-I and SECS-II, establishment of communication session timeout.\n * @param timeoutT6 Only HSMS supports this parameter, reply control message timeout.\n * @param timeoutT7 Only HSMS supports this parameter, create connection timeout.\n * @param timeoutT8 Only HSMS supports this parameter, the maximum time interval between message bytes when receiving a message\n */\nexport interface SecsCommunicatorConfig {\n\tdeviceId: number;\n\tisEquip: boolean;\n\tname?: string;\n\ttimeoutT1?: number;\n\ttimeoutT2?: number;\n\ttimeoutT3?: number;\n\ttimeoutT4?: number;\n\ttimeoutT5?: number;\n\ttimeoutT6?: number;\n\ttimeoutT7?: number;\n\ttimeoutT8?: number;\n}\n\nexport abstract class AbstractSecsCommunicator<\n\tEvents extends Record<keyof Events, unknown[]> & SecsCommunicatorEvents =\n\t\tSecsCommunicatorEvents,\n> extends EventEmitter {\n\tpublic readonly deviceId: number;\n\tpublic readonly isEquip: boolean;\n\tpublic readonly name: string;\n\n\tpublic timeoutT1 = 1;\n\tpublic timeoutT2 = 15;\n\tpublic timeoutT3 = 45;\n\tpublic timeoutT4 = 45;\n\tpublic timeoutT5 = 10;\n\tpublic timeoutT6 = 5;\n\tpublic timeoutT7 = 10;\n\tpublic timeoutT8 = 5;\n\n\tprotected _systemBytesCounter = 0;\n\tprotected _transactions = new Map<\n\t\tnumber,\n\t\t{\n\t\t\tresolve: (msg: SecsMessage) => void;\n\t\t\treject: (err: Error) => void;\n\t\t\ttimer: NodeJS.Timeout;\n\t\t}\n\t>();\n\n\tconstructor(config: SecsCommunicatorConfig) {\n\t\tsuper();\n\t\tthis.deviceId = config.deviceId;\n\t\tthis.isEquip = config.isEquip;\n\t\tthis.name = config.name ?? \"SecsCommunicator\";\n\t\tif (config.timeoutT1 !== undefined) this.timeoutT1 = config.timeoutT1;\n\t\tif (config.timeoutT2 !== undefined) this.timeoutT2 = config.timeoutT2;\n\t\tif (config.timeoutT3 !== undefined) this.timeoutT3 = config.timeoutT3;\n\t\tif (config.timeoutT4 !== undefined) this.timeoutT4 = config.timeoutT4;\n\t\tif (config.timeoutT5 !== undefined) this.timeoutT5 = config.timeoutT5;\n\t\tif (config.timeoutT6 !== undefined) this.timeoutT6 = config.timeoutT6;\n\t\tif (config.timeoutT7 !== undefined) this.timeoutT7 = config.timeoutT7;\n\t\tif (config.timeoutT8 !== undefined) this.timeoutT8 = config.timeoutT8;\n\t}\n\n\tabstract open(): Promise<void>;\n\tabstract close(): Promise<void>;\n\n\tprotected emitInternal(\n\t\teventName: string | symbol,\n\t\t...args: unknown[]\n\t): boolean {\n\t\treturn (\n\t\t\tsuper.emit as (\n\t\t\t\tthis: AbstractSecsCommunicator<Events>,\n\t\t\t\teventName: string | symbol,\n\t\t\t\t...args: unknown[]\n\t\t\t) => boolean\n\t\t).call(this, eventName, ...args);\n\t}\n\n\t// This method sends the message bytes. To be implemented by subclasses.\n\tprotected abstract sendBuffer(buffer: Buffer): Promise<void>;\n\n\tprotected abstract createMessage(\n\t\tstream: number,\n\t\tfunc: number,\n\t\twBit: boolean,\n\t\tbody: AbstractSecs2Item | null,\n\t\tsystemBytes: number,\n\t): SecsMessage;\n\n\tasync send(\n\t\tstream: number,\n\t\tfunc: number,\n\t\twBit: boolean,\n\t\tbody: AbstractSecs2Item | null = null,\n\t): Promise<SecsMessage | null> {\n\t\tconst systemBytes = this.getNextSystemBytes();\n\t\tconst msg = this.createMessage(stream, func, wBit, body, systemBytes);\n\n\t\tif (wBit) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tconst timer = setTimeout(() => {\n\t\t\t\t\tif (this._transactions.has(systemBytes)) {\n\t\t\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\t\t\treject(\n\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t`T3 Timeout waiting for reply to S${String(stream)}F${String(func)} [SysBytes=${String(systemBytes)}]`,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}, this.timeoutT3 * 1000);\n\n\t\t\t\tthis._transactions.set(systemBytes, { resolve, reject, timer });\n\n\t\t\t\tthis.sendBuffer(msg.toBuffer()).catch((err: unknown) => {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\t\treject(err instanceof Error ? err : new Error(String(err)));\n\t\t\t\t});\n\t\t\t});\n\t\t} else {\n\t\t\tawait this.sendBuffer(msg.toBuffer());\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync reply(\n\t\tprimaryMsg: SecsMessage,\n\t\tstream: number,\n\t\tfunc: number,\n\t\tbody: AbstractSecs2Item | null = null,\n\t): Promise<void> {\n\t\tconst msg = this.createMessage(\n\t\t\tstream,\n\t\t\tfunc,\n\t\t\tfalse,\n\t\t\tbody,\n\t\t\tprimaryMsg.systemBytes,\n\t\t);\n\t\tconsole.log(\"Reply Buffer:\", msg.toBuffer());\n\t\tconsole.log(`Reply: ${msg.toSml()}`);\n\t\tawait this.sendBuffer(msg.toBuffer());\n\t}\n\n\tprotected getNextSystemBytes(): number {\n\t\tthis._systemBytesCounter = (this._systemBytesCounter + 1) >>> 0; // Ensure 32-bit unsigned\n\t\treturn this._systemBytesCounter;\n\t}\n\n\tprotected handleMessage(msg: SecsMessage) {\n\t\t// Check if it's a reply\n\t\t// Usually, if we have a transaction waiting for this SystemBytes, we treat it as a reply.\n\t\t// However, Stream 0 (HSMS Control) messages are never replies to SECS-II messages.\n\t\t// SECS-II replies usually have the same SystemBytes as the primary.\n\n\t\tconst tx = this._transactions.get(msg.systemBytes);\n\t\tif (tx) {\n\t\t\tclearTimeout(tx.timer);\n\t\t\tthis._transactions.delete(msg.systemBytes);\n\t\t\ttx.resolve(msg);\n\t\t\treturn;\n\t\t}\n\n\t\t// If not a reply, emit event\n\t\tthis.emitInternal(\"message\", msg);\n\t}\n}\n"],"mappings":";;;AA4CA,IAAsB,2BAAtB,cAGU,aAAa;CACtB,AAAgB;CAChB,AAAgB;CAChB,AAAgB;CAEhB,AAAO,YAAY;CACnB,AAAO,YAAY;CACnB,AAAO,YAAY;CACnB,AAAO,YAAY;CACnB,AAAO,YAAY;CACnB,AAAO,YAAY;CACnB,AAAO,YAAY;CACnB,AAAO,YAAY;CAEnB,AAAU,sBAAsB;CAChC,AAAU,gCAAgB,IAAI,KAO3B;CAEH,YAAY,QAAgC;AAC3C,SAAO;AACP,OAAK,WAAW,OAAO;AACvB,OAAK,UAAU,OAAO;AACtB,OAAK,OAAO,OAAO,QAAQ;AAC3B,MAAI,OAAO,cAAc,OAAW,MAAK,YAAY,OAAO;AAC5D,MAAI,OAAO,cAAc,OAAW,MAAK,YAAY,OAAO;AAC5D,MAAI,OAAO,cAAc,OAAW,MAAK,YAAY,OAAO;AAC5D,MAAI,OAAO,cAAc,OAAW,MAAK,YAAY,OAAO;AAC5D,MAAI,OAAO,cAAc,OAAW,MAAK,YAAY,OAAO;AAC5D,MAAI,OAAO,cAAc,OAAW,MAAK,YAAY,OAAO;AAC5D,MAAI,OAAO,cAAc,OAAW,MAAK,YAAY,OAAO;AAC5D,MAAI,OAAO,cAAc,OAAW,MAAK,YAAY,OAAO;;CAM7D,AAAU,aACT,WACA,GAAG,MACO;AACV,SACC,MAAM,KAKL,KAAK,MAAM,WAAW,GAAG,KAAK;;CAcjC,MAAM,KACL,QACA,MACA,MACA,OAAiC,MACH;EAC9B,MAAM,cAAc,KAAK,oBAAoB;EAC7C,MAAM,MAAM,KAAK,cAAc,QAAQ,MAAM,MAAM,MAAM,YAAY;AAErE,MAAI,KACH,QAAO,IAAI,SAAS,SAAS,WAAW;GACvC,MAAM,QAAQ,iBAAiB;AAC9B,QAAI,KAAK,cAAc,IAAI,YAAY,EAAE;AACxC,UAAK,cAAc,OAAO,YAAY;AACtC,4BACC,IAAI,MACH,oCAAoC,OAAO,OAAO,CAAC,GAAG,OAAO,KAAK,CAAC,aAAa,OAAO,YAAY,CAAC,GACpG,CACD;;MAEA,KAAK,YAAY,IAAK;AAEzB,QAAK,cAAc,IAAI,aAAa;IAAE;IAAS;IAAQ;IAAO,CAAC;AAE/D,QAAK,WAAW,IAAI,UAAU,CAAC,CAAC,OAAO,QAAiB;AACvD,iBAAa,MAAM;AACnB,SAAK,cAAc,OAAO,YAAY;AACtC,WAAO,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC,CAAC;KAC1D;IACD;OACI;AACN,SAAM,KAAK,WAAW,IAAI,UAAU,CAAC;AACrC,UAAO;;;CAIT,MAAM,MACL,YACA,QACA,MACA,OAAiC,MACjB;EAChB,MAAM,MAAM,KAAK,cAChB,QACA,MACA,OACA,MACA,WAAW,YACX;AACD,UAAQ,IAAI,iBAAiB,IAAI,UAAU,CAAC;AAC5C,UAAQ,IAAI,UAAU,IAAI,OAAO,GAAG;AACpC,QAAM,KAAK,WAAW,IAAI,UAAU,CAAC;;CAGtC,AAAU,qBAA6B;AACtC,OAAK,sBAAuB,KAAK,sBAAsB,MAAO;AAC9D,SAAO,KAAK;;CAGb,AAAU,cAAc,KAAkB;EAMzC,MAAM,KAAK,KAAK,cAAc,IAAI,IAAI,YAAY;AAClD,MAAI,IAAI;AACP,gBAAa,GAAG,MAAM;AACtB,QAAK,cAAc,OAAO,IAAI,YAAY;AAC1C,MAAG,QAAQ,IAAI;AACf;;AAID,OAAK,aAAa,WAAW,IAAI"}
@@ -0,0 +1,36 @@
1
+ import { AbstractSecs2Item } from "./secs2item/AbstractSecs2Item.js";
2
+
3
+ //#region src/core/AbstractSecsMessage.d.ts
4
+
5
+ /**
6
+ * @param stream The stream number.
7
+ * @param func The function number.
8
+ * @param wBit Whether the message is a request.
9
+ * @param body The body of the message.
10
+ * @param systemBytes The system bytes.
11
+ * @param deviceId The device ID.
12
+ */
13
+ declare class SecsMessage {
14
+ readonly stream: number;
15
+ readonly func: number;
16
+ readonly wBit: boolean;
17
+ readonly body: AbstractSecs2Item | null;
18
+ readonly systemBytes: number;
19
+ readonly deviceId: number;
20
+ constructor(stream: number, func: number, wBit: boolean, body?: AbstractSecs2Item | null, systemBytes?: number,
21
+ // Typically 4 bytes, treated as integer for convenience if it fits, or Buffer
22
+ deviceId?: number);
23
+ /**
24
+ * @description Returns the SML representation of the message.
25
+ * @returns The SML representation.
26
+ */
27
+ toSml(): string;
28
+ /**
29
+ * @description Returns the binary representation of the message.
30
+ * @returns The binary representation.
31
+ */
32
+ toBuffer(): Buffer;
33
+ }
34
+ //#endregion
35
+ export { SecsMessage };
36
+ //# sourceMappingURL=AbstractSecsMessage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractSecsMessage.d.ts","names":[],"sources":["../../src/core/AbstractSecsMessage.ts"],"sourcesContent":[],"mappings":";;;;;;AAUA;;;;;;cAAa,WAAA;;;;iBAKW;;;kEAAA;;;;;;;;;;;;cAyBX"}