@zimo-elektronik/zcan 1.0.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 (202) hide show
  1. package/.dockerignore +7 -0
  2. package/.editorconfig +15 -0
  3. package/.eslintignore +7 -0
  4. package/.eslintrc.cjs +17 -0
  5. package/.gitattributes +1 -0
  6. package/.github/workflows/docs.yml +46 -0
  7. package/.github/workflows/library.yml +59 -0
  8. package/.nvmrc +1 -0
  9. package/.prettierignore +14 -0
  10. package/.prettierrc.json +8 -0
  11. package/LICENSE.md +21 -0
  12. package/README.md +8 -0
  13. package/__tests__/connection.test.ts +58 -0
  14. package/__tests__/dataGroup.test.ts +98 -0
  15. package/__tests__/infoGroup.test.ts +30 -0
  16. package/__tests__/lanDataGroup.test.ts +82 -0
  17. package/__tests__/lanInfoGroup.test.ts +41 -0
  18. package/__tests__/systemControlGroup.test.ts +42 -0
  19. package/__tests__/trackCfgGroup.test.ts +43 -0
  20. package/__tests__/util/index.ts +14 -0
  21. package/__tests__/vehicleGroup.test.ts +128 -0
  22. package/dist/@types/communication.d.ts +30 -0
  23. package/dist/@types/communication.js +2 -0
  24. package/dist/@types/communication.js.map +1 -0
  25. package/dist/@types/models.d.ts +172 -0
  26. package/dist/@types/models.js +2 -0
  27. package/dist/@types/models.js.map +1 -0
  28. package/dist/MX10.d.ts +45 -0
  29. package/dist/MX10.js +233 -0
  30. package/dist/MX10.js.map +1 -0
  31. package/dist/docs_entrypoint.d.ts +6 -0
  32. package/dist/docs_entrypoint.js +7 -0
  33. package/dist/docs_entrypoint.js.map +1 -0
  34. package/dist/index.d.ts +6 -0
  35. package/dist/index.js +7 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/internal/bites.d.ts +9 -0
  38. package/dist/internal/bites.js +10 -0
  39. package/dist/internal/bites.js.map +1 -0
  40. package/dist/internal/speedUtils.d.ts +9 -0
  41. package/dist/internal/speedUtils.js +29 -0
  42. package/dist/internal/speedUtils.js.map +1 -0
  43. package/dist/internal/utils.d.ts +1 -0
  44. package/dist/internal/utils.js +4 -0
  45. package/dist/internal/utils.js.map +1 -0
  46. package/dist/util/enums.d.ts +113 -0
  47. package/dist/util/enums.js +137 -0
  48. package/dist/util/enums.js.map +1 -0
  49. package/dist/util/extended-ascii.d.ts +7 -0
  50. package/dist/util/extended-ascii.js +162 -0
  51. package/dist/util/extended-ascii.js.map +1 -0
  52. package/dist/zcan/accessoryCommandGroup.d.ts +6 -0
  53. package/dist/zcan/accessoryCommandGroup.js +9 -0
  54. package/dist/zcan/accessoryCommandGroup.js.map +1 -0
  55. package/dist/zcan/dataGroup.d.ts +31 -0
  56. package/dist/zcan/dataGroup.js +233 -0
  57. package/dist/zcan/dataGroup.js.map +1 -0
  58. package/dist/zcan/fileControlGroup.d.ts +7 -0
  59. package/dist/zcan/fileControlGroup.js +9 -0
  60. package/dist/zcan/fileControlGroup.js.map +1 -0
  61. package/dist/zcan/fileTransferGroup.d.ts +7 -0
  62. package/dist/zcan/fileTransferGroup.js +9 -0
  63. package/dist/zcan/fileTransferGroup.js.map +1 -0
  64. package/dist/zcan/index.d.ts +18 -0
  65. package/dist/zcan/index.js +19 -0
  66. package/dist/zcan/index.js.map +1 -0
  67. package/dist/zcan/infoGroup.d.ts +15 -0
  68. package/dist/zcan/infoGroup.js +64 -0
  69. package/dist/zcan/infoGroup.js.map +1 -0
  70. package/dist/zcan/lanDataGroup.d.ts +23 -0
  71. package/dist/zcan/lanDataGroup.js +226 -0
  72. package/dist/zcan/lanDataGroup.js.map +1 -0
  73. package/dist/zcan/lanInfoGroup.d.ts +11 -0
  74. package/dist/zcan/lanInfoGroup.js +58 -0
  75. package/dist/zcan/lanInfoGroup.js.map +1 -0
  76. package/dist/zcan/lanNetworkGroup.d.ts +11 -0
  77. package/dist/zcan/lanNetworkGroup.js +37 -0
  78. package/dist/zcan/lanNetworkGroup.js.map +1 -0
  79. package/dist/zcan/lanZimoProgrammableScriptGroup.d.ts +7 -0
  80. package/dist/zcan/lanZimoProgrammableScriptGroup.js +9 -0
  81. package/dist/zcan/lanZimoProgrammableScriptGroup.js.map +1 -0
  82. package/dist/zcan/networkGroup.d.ts +10 -0
  83. package/dist/zcan/networkGroup.js +38 -0
  84. package/dist/zcan/networkGroup.js.map +1 -0
  85. package/dist/zcan/propertyConfigGroup.d.ts +7 -0
  86. package/dist/zcan/propertyConfigGroup.js +9 -0
  87. package/dist/zcan/propertyConfigGroup.js.map +1 -0
  88. package/dist/zcan/railwayControlGroup.d.ts +7 -0
  89. package/dist/zcan/railwayControlGroup.js +9 -0
  90. package/dist/zcan/railwayControlGroup.js.map +1 -0
  91. package/dist/zcan/systemControlGroup.d.ts +13 -0
  92. package/dist/zcan/systemControlGroup.js +35 -0
  93. package/dist/zcan/systemControlGroup.js.map +1 -0
  94. package/dist/zcan/trackCfgGroup.d.ts +16 -0
  95. package/dist/zcan/trackCfgGroup.js +77 -0
  96. package/dist/zcan/trackCfgGroup.js.map +1 -0
  97. package/dist/zcan/trainControlGroup.d.ts +8 -0
  98. package/dist/zcan/trainControlGroup.js +19 -0
  99. package/dist/zcan/trainControlGroup.js.map +1 -0
  100. package/dist/zcan/vehicleGroup.d.ts +26 -0
  101. package/dist/zcan/vehicleGroup.js +145 -0
  102. package/dist/zcan/vehicleGroup.js.map +1 -0
  103. package/dist/zcan/zimoProgrammableScriptGroup.d.ts +7 -0
  104. package/dist/zcan/zimoProgrammableScriptGroup.js +9 -0
  105. package/dist/zcan/zimoProgrammableScriptGroup.js.map +1 -0
  106. package/gulpfile.js +37 -0
  107. package/jest.config.js +26 -0
  108. package/package.json +50 -0
  109. package/protocol_docs/README.md +41 -0
  110. package/protocol_docs/babel.config.js +3 -0
  111. package/protocol_docs/docs/command-groups/_category_.json +4 -0
  112. package/protocol_docs/docs/command-groups/accessories/_category_.json +4 -0
  113. package/protocol_docs/docs/command-groups/accessories/accessory-state.md +7 -0
  114. package/protocol_docs/docs/command-groups/command-groups.md +50 -0
  115. package/protocol_docs/docs/command-groups/data/_category_.json +4 -0
  116. package/protocol_docs/docs/command-groups/data/data-name-extended.md +60 -0
  117. package/protocol_docs/docs/command-groups/data/group-count.md +52 -0
  118. package/protocol_docs/docs/command-groups/data/item-fx-info.md +27 -0
  119. package/protocol_docs/docs/command-groups/data/item-image-config.md +44 -0
  120. package/protocol_docs/docs/command-groups/data/item-list-by-index.md +45 -0
  121. package/protocol_docs/docs/command-groups/data/item-list-by-nid.md +43 -0
  122. package/protocol_docs/docs/command-groups/data/remove-train.md +33 -0
  123. package/protocol_docs/docs/command-groups/info/_category_.json +4 -0
  124. package/protocol_docs/docs/command-groups/info/bidi-info.md +34 -0
  125. package/protocol_docs/docs/command-groups/lan-data/_category_.json +4 -0
  126. package/protocol_docs/docs/command-groups/lan-data/data-value-extended.md +65 -0
  127. package/protocol_docs/docs/command-groups/lan-data/loco-gui-extended.md +48 -0
  128. package/protocol_docs/docs/command-groups/lan-info/_category_.json +4 -0
  129. package/protocol_docs/docs/command-groups/lan-info/module-power-info.md +26 -0
  130. package/protocol_docs/docs/command-groups/lan-network/_category_.json +4 -0
  131. package/protocol_docs/docs/command-groups/lan-network/open-port.md +47 -0
  132. package/protocol_docs/docs/command-groups/network/_category_.json +4 -0
  133. package/protocol_docs/docs/command-groups/network/ping.md +49 -0
  134. package/protocol_docs/docs/command-groups/system/_category_.json +4 -0
  135. package/protocol_docs/docs/command-groups/system/system-state.md +59 -0
  136. package/protocol_docs/docs/command-groups/track/_category_.json +4 -0
  137. package/protocol_docs/docs/command-groups/track/tse-prog-read.md +37 -0
  138. package/protocol_docs/docs/command-groups/track/tse-prog-write.md +35 -0
  139. package/protocol_docs/docs/command-groups/train/_category_.json +4 -0
  140. package/protocol_docs/docs/command-groups/train/train-part-find.md +33 -0
  141. package/protocol_docs/docs/command-groups/vehicles/_category_.json +4 -0
  142. package/protocol_docs/docs/command-groups/vehicles/vehicle-function.md +36 -0
  143. package/protocol_docs/docs/command-groups/vehicles/vehicle-mode.md +143 -0
  144. package/protocol_docs/docs/command-groups/vehicles/vehicle-special-function-switch.md +35 -0
  145. package/protocol_docs/docs/command-groups/vehicles/vehicle-speed.md +55 -0
  146. package/protocol_docs/docs/description.md +4 -0
  147. package/protocol_docs/docs/introduction/_category_.json +4 -0
  148. package/protocol_docs/docs/introduction/how-it-works.md +61 -0
  149. package/protocol_docs/docs/introduction/implementation.md +39 -0
  150. package/protocol_docs/docs/introduction/interface.md +62 -0
  151. package/protocol_docs/docs/introduction/introduction.md +82 -0
  152. package/protocol_docs/docusaurus.config.js +111 -0
  153. package/protocol_docs/package-lock.json +25611 -0
  154. package/protocol_docs/package.json +47 -0
  155. package/protocol_docs/sidebars.js +22 -0
  156. package/protocol_docs/src/components/CommandAndGroup/index.tsx +16 -0
  157. package/protocol_docs/src/components/CommandAndGroup/styles.module.css +12 -0
  158. package/protocol_docs/src/components/HomepageFeatures/index.tsx +70 -0
  159. package/protocol_docs/src/components/HomepageFeatures/styles.module.css +11 -0
  160. package/protocol_docs/src/css/custom.css +76 -0
  161. package/protocol_docs/src/pages/index.module.css +23 -0
  162. package/protocol_docs/src/pages/index.tsx +41 -0
  163. package/protocol_docs/src/pages/markdown-page.md +7 -0
  164. package/protocol_docs/static/.nojekyll +0 -0
  165. package/protocol_docs/static/img/docusaurus.png +0 -0
  166. package/protocol_docs/static/img/favicon.ico +0 -0
  167. package/protocol_docs/static/img/undraw_docusaurus_mountain.svg +171 -0
  168. package/protocol_docs/static/img/undraw_docusaurus_react.svg +170 -0
  169. package/protocol_docs/static/img/undraw_docusaurus_tree.svg +40 -0
  170. package/protocol_docs/static/typedoc/index.html +10 -0
  171. package/protocol_docs/tsconfig.json +7 -0
  172. package/src/@types/communication.ts +73 -0
  173. package/src/@types/models.ts +215 -0
  174. package/src/MX10.ts +351 -0
  175. package/src/docs_entrypoint.ts +34 -0
  176. package/src/index.ts +8 -0
  177. package/src/internal/bites.ts +11 -0
  178. package/src/internal/speedUtils.ts +36 -0
  179. package/src/internal/utils.ts +3 -0
  180. package/src/util/enums.ts +147 -0
  181. package/src/util/extended-ascii.ts +179 -0
  182. package/src/zcan/accessoryCommandGroup.ts +24 -0
  183. package/src/zcan/dataGroup.ts +342 -0
  184. package/src/zcan/fileControlGroup.ts +25 -0
  185. package/src/zcan/fileTransferGroup.ts +25 -0
  186. package/src/zcan/index.ts +37 -0
  187. package/src/zcan/infoGroup.ts +90 -0
  188. package/src/zcan/lanDataGroup.ts +361 -0
  189. package/src/zcan/lanInfoGroup.ts +86 -0
  190. package/src/zcan/lanNetworkGroup.ts +70 -0
  191. package/src/zcan/lanZimoProgrammableScriptGroup.ts +25 -0
  192. package/src/zcan/networkGroup.ts +71 -0
  193. package/src/zcan/propertyConfigGroup.ts +25 -0
  194. package/src/zcan/railwayControlGroup.ts +25 -0
  195. package/src/zcan/systemControlGroup.ts +62 -0
  196. package/src/zcan/trackCfgGroup.ts +109 -0
  197. package/src/zcan/trainControlGroup.ts +48 -0
  198. package/src/zcan/vehicleGroup.ts +267 -0
  199. package/src/zcan/zimoProgrammableScriptGroup.ts +25 -0
  200. package/tsconfig.build.json +12 -0
  201. package/tsconfig.json +49 -0
  202. package/tsconfig.test.json +9 -0
@@ -0,0 +1,361 @@
1
+ // 0x17
2
+ import MX10 from '../MX10';
3
+ import {FunctionMode, getOperatingMode, OperatingMode} from '../util/enums';
4
+ import {
5
+ DataValueExtendedData,
6
+ LocoGuiMXExtended,
7
+ LocoSpeedTabExtended,
8
+ SpeedTabData,
9
+ Train,
10
+ TrainFlags,
11
+ TrainFunction,
12
+ } from '../@types/models';
13
+ import {Subject} from 'rxjs';
14
+ import {parseSpeed} from '../internal/speedUtils';
15
+ import ExtendedASCII from '../util/extended-ascii';
16
+ import {manualModeB, shuntingFunctionB} from '../internal/bites';
17
+
18
+ /**
19
+ *
20
+ * @category Groups
21
+ */
22
+ export default class LanDataGroup {
23
+ public readonly onLocoGuiExtended = new Subject<Train>();
24
+ public readonly onLocoGuiMXExtended = new Subject<LocoGuiMXExtended>();
25
+ public readonly onDataValueExtended = new Subject<DataValueExtendedData>();
26
+ public readonly onLocoSpeedTabExtended = new Subject<LocoSpeedTabExtended>();
27
+
28
+ private mx10: MX10;
29
+
30
+ constructor(mx10: MX10) {
31
+ this.mx10 = mx10;
32
+ }
33
+
34
+ locoGuiExtended(NID: number) {
35
+ this.mx10.sendData(
36
+ 0x17,
37
+ 0x27,
38
+ [
39
+ {value: this.mx10.mx10NID, length: 2},
40
+ {value: NID, length: 2},
41
+ {value: 0, length: 2},
42
+ ],
43
+ 0b00,
44
+ );
45
+ }
46
+
47
+ locoGuiMXExtended(NID: number) {
48
+ this.mx10.sendData(
49
+ 0x17,
50
+ 0x28,
51
+ [
52
+ {value: this.mx10.mx10NID, length: 2},
53
+ {value: NID, length: 2},
54
+ {value: 0, length: 2},
55
+ ],
56
+ 0b00,
57
+ );
58
+ }
59
+
60
+ dataValueExtended(NID: number) {
61
+ this.mx10.sendData(
62
+ 0x17,
63
+ 0x08,
64
+ [
65
+ {value: this.mx10.mx10NID, length: 2},
66
+ {value: NID, length: 2},
67
+ {value: 1, length: 2},
68
+ ],
69
+ 0b00,
70
+ );
71
+ }
72
+
73
+ locoSpeedTapExtended(NID: number) {
74
+ this.mx10.sendData(
75
+ 0x17,
76
+ 0x19,
77
+ [
78
+ {value: this.mx10.mx10NID, length: 2},
79
+ {value: NID, length: 2},
80
+ {value: 0, length: 1},
81
+ {value: 0, length: 1},
82
+ ],
83
+ 0b00,
84
+ );
85
+ }
86
+
87
+ parse(
88
+ size: number,
89
+ command: number,
90
+ mode: number,
91
+ nid: number,
92
+ buffer: Buffer,
93
+ ) {
94
+ switch (command) {
95
+ case 0x08:
96
+ this.parseDataValueExtended(size, mode, nid, buffer);
97
+ break;
98
+ case 0x27:
99
+ this.parseLocoGuiExtended(size, mode, nid, buffer);
100
+ break;
101
+ case 0x28:
102
+ this.parseLocoGuiMXExtended(size, mode, nid, buffer);
103
+ break;
104
+ case 0x19:
105
+ this.parseLocoSpeedTabExtended(size, mode, nid, buffer);
106
+ break;
107
+ }
108
+ }
109
+
110
+ // 0x17.0x08
111
+ private parseDataValueExtended(
112
+ size: number,
113
+ mode: number,
114
+ nid: number,
115
+ buffer: Buffer,
116
+ ) {
117
+ if (this.onDataValueExtended.observed) {
118
+ const NID = buffer.readUInt16LE(0);
119
+ const deletedFlag = buffer.readUInt8(4);
120
+ const flagsBytes = buffer.readUInt32LE(4);
121
+ const trackMode = buffer.readUInt8(24);
122
+ const functionCount = buffer.readUInt8(25);
123
+ const speedAndDirection = buffer.readUInt16LE(44);
124
+
125
+ const {speedStep, forward, eastWest, emergencyStop} =
126
+ parseSpeed(speedAndDirection);
127
+ const operatingMode = getOperatingMode(trackMode);
128
+ const flags = this.parseFlags(flagsBytes);
129
+
130
+ let functions = buffer.readUInt32LE(46);
131
+ const functionsStates = [];
132
+ for (let i = 0; i < 31; i++) {
133
+ const active = (functions & 1) == 1;
134
+ functionsStates.push(active);
135
+ functions = functions >> 1;
136
+ }
137
+
138
+ const specialFunc = buffer.readUInt32LE(50);
139
+
140
+ const shuntingFunction = specialFunc & shuntingFunctionB;
141
+ const manualMode = (specialFunc & manualModeB) >> 4;
142
+
143
+ const deleted = this.parseDeleted(deletedFlag);
144
+
145
+ this.onDataValueExtended.next({
146
+ nid: NID,
147
+ flags,
148
+ functionCount,
149
+ speedStep,
150
+ forward,
151
+ eastWest,
152
+ emergencyStop,
153
+ operatingMode,
154
+ functionsStates,
155
+ shuntingFunction,
156
+ manualMode,
157
+ deleted,
158
+ });
159
+ }
160
+ }
161
+
162
+ // 0x17.0x27
163
+ private parseLocoGuiExtended(
164
+ size: number,
165
+ mode: number,
166
+ nid: number,
167
+ buffer: Buffer,
168
+ ) {
169
+ if (this.onLocoGuiExtended.observed) {
170
+ const NID = buffer.readUInt16LE(0);
171
+ const SubID = buffer.readUInt16LE(2);
172
+ const vehicleGroup = buffer.readUInt16LE(4);
173
+
174
+ const name = ExtendedASCII.byte2str(buffer.subarray(6, 32));
175
+ const imageId = buffer.readUInt16LE(38);
176
+ const tacho = buffer.readUInt16LE(40);
177
+ const speedFwd = buffer.readUInt16LE(42);
178
+ const speedRev = buffer.readUInt16LE(44);
179
+ const speedRange = buffer.readUInt16LE(46);
180
+ const driveType = buffer.readUInt16LE(48);
181
+ const era = buffer.readUInt16LE(50);
182
+ const countryCode = buffer.readUInt16LE(52);
183
+
184
+ // reading 64 bytes of functions
185
+ const functions = Array<TrainFunction>();
186
+ for (let i = 0; i < 33; i++) {
187
+ const icon = buffer.readUInt16LE(54 + i * 2);
188
+ const iconString =
189
+ icon === 0 ? String(i).padStart(2, '0') : String(icon);
190
+ functions.push({
191
+ mode: FunctionMode.switch,
192
+ active: false,
193
+ icon: iconString.padStart(4, icon === 0 ? '07' : '0'),
194
+ });
195
+ }
196
+ this.onLocoGuiExtended.next({
197
+ nid: NID,
198
+ subId: SubID,
199
+ name: name,
200
+ group: vehicleGroup,
201
+ image: imageId == 0 ? undefined : imageId.toString(),
202
+ tacho: tacho.toString(),
203
+ speedFwd: speedFwd,
204
+ speedRev: speedRev,
205
+ speedRange: speedRange,
206
+ operatingMode: OperatingMode.UNKNOWN,
207
+ driveType: driveType,
208
+ era: this.parseEra(era),
209
+ countryCode: countryCode,
210
+ functions,
211
+ });
212
+ }
213
+ }
214
+
215
+ // 0x17.0x28
216
+ private parseLocoGuiMXExtended(
217
+ size: number,
218
+ mode: number,
219
+ nid: number,
220
+ buffer: Buffer,
221
+ ) {
222
+ if (this.onLocoGuiMXExtended.observed) {
223
+ const NID = buffer.readUInt16LE(0);
224
+
225
+ // TODO: after documentation
226
+ // const SubID = buffer.readUInt16LE(2);
227
+ // const vehicleGroup = buffer.readUInt16LE(4);
228
+
229
+ // const name = ExtendedASCII.byte2str(buffer.subarray(6, 32));
230
+ // const imageId = buffer.readUInt16LE(38);
231
+ // const tacho = buffer.readUInt16LE(40);
232
+ // const speedFwd = buffer.readUInt16LE(42);
233
+ // const speedRev = buffer.readUInt16LE(44);
234
+ // const speedRange = buffer.readUInt16LE(46);
235
+ // const driveType = buffer.readUInt16LE(48);
236
+ // const era = buffer.readUInt16LE(50);
237
+ // const countryCode = buffer.readUInt16LE(52);
238
+
239
+ // reading 64 bytes of functions
240
+ const functions = Array<TrainFunction>();
241
+ for (let i = 0; i < 33; i++) {
242
+ const icon = buffer.readUInt16LE(68 + i * 2);
243
+ const iconString =
244
+ icon === 0 ? String(i).padStart(2, '0') : String(icon);
245
+ functions.push({
246
+ mode: FunctionMode.switch,
247
+ active: false,
248
+ icon: iconString.padStart(4, icon === 0 ? '07' : '0'),
249
+ });
250
+ }
251
+
252
+ //TODO: implement rest
253
+ this.onLocoGuiMXExtended.next({
254
+ nid: NID,
255
+ // subId: SubID,
256
+ // name: name,
257
+ // group: vehicleGroup,
258
+ // image: imageId == 0 ? undefined : imageId.toString(),
259
+ // tacho: tacho.toString(),
260
+ // speedFwd: speedFwd,
261
+ // speedRev: speedRev,
262
+ // speedRange: speedRange,
263
+ // operatingMode: OperatingMode.UNKNOWN,
264
+ // driveType: driveType,
265
+ // era: this.parseEra(era),
266
+ // countryCode: countryCode,
267
+ functions,
268
+ });
269
+ }
270
+ }
271
+
272
+ // 0x17.0x19
273
+ private parseLocoSpeedTabExtended(
274
+ size: number,
275
+ mode: number,
276
+ nid: number,
277
+ buffer: Buffer,
278
+ ) {
279
+ if (this.onLocoSpeedTabExtended.observed) {
280
+ const setDBat6 = 5;
281
+ const bufferLengthOfSpeedTab = 24;
282
+
283
+ const SrcID = buffer.readUInt16LE(0);
284
+ const NID = buffer.readUInt16LE(2);
285
+ const DBat6 = buffer.readUInt8(5);
286
+ // const speedStep0 = buffer.readUInt16LE(6);
287
+ // const speed0 = buffer.readUInt16LE(8);
288
+ // const speedStep1 = buffer.readUInt16LE(10);
289
+ // const speed1 = buffer.readUInt16LE(12);
290
+ // const speedStep2 = buffer.readUInt16LE(14);
291
+ // const speed2 = buffer.readUInt16LE(16);
292
+ // const speedStep3 = buffer.readUInt16LE(18);
293
+ // const speed3 = buffer.readUInt16LE(20);
294
+ // const speedStep4 = buffer.readUInt16LE(22);
295
+ // const speed4 = buffer.readUInt16LE(24);
296
+
297
+ let locoSpeedTab: Array<SpeedTabData> | undefined = undefined;
298
+
299
+ if (DBat6 !== setDBat6) {
300
+ locoSpeedTab = undefined;
301
+ } else {
302
+ locoSpeedTab = [];
303
+
304
+ for (let i = 0; i < 4; i++) {
305
+ const offset = 6 + i * 4;
306
+ if (bufferLengthOfSpeedTab >= offset + 2) {
307
+ const speedStep = buffer.readUInt16LE(offset);
308
+ const speed = buffer.readUInt16LE(offset + 2);
309
+ locoSpeedTab.push({
310
+ id: i + 1,
311
+ speedStep: speedStep,
312
+ speed: speed,
313
+ });
314
+ } else {
315
+ // eslint-disable-next-line no-console
316
+ console.warn(`Train with id:${NID} has wrong speedStepTab buffer`);
317
+ break;
318
+ }
319
+ }
320
+ }
321
+
322
+ this.onLocoSpeedTabExtended.next({
323
+ srcid: SrcID,
324
+ nid: NID,
325
+ dbat6: DBat6,
326
+ speedTab: locoSpeedTab,
327
+ });
328
+ }
329
+ }
330
+
331
+ private parseEra(eraString: number) {
332
+ switch (eraString & 0xf0) {
333
+ case 0x10:
334
+ return 'I';
335
+ case 0x20:
336
+ return 'II';
337
+ case 0x30:
338
+ return 'III';
339
+ case 0x40:
340
+ return 'IV';
341
+ case 0x50:
342
+ return 'V';
343
+ case 0x60:
344
+ return 'VI';
345
+ case 0x70:
346
+ return 'VII';
347
+ default:
348
+ return '';
349
+ }
350
+ }
351
+
352
+ private parseFlags(flagsNumber: number): TrainFlags {
353
+ return {
354
+ deleted: flagsNumber >> 31 === 1,
355
+ };
356
+ }
357
+
358
+ private parseDeleted(parseDeletedFlag: number) {
359
+ return parseDeletedFlag === 1;
360
+ }
361
+ }
@@ -0,0 +1,86 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-vars */
2
+ // 0x18
3
+ import MX10 from '../MX10';
4
+ import {Subject} from 'rxjs';
5
+ import {ModulePowerInfoData} from '../@types/models';
6
+ import {TrackMode} from '../util/enums';
7
+
8
+ /**
9
+ *
10
+ * @category Groups
11
+ */
12
+ export default class LanInfoGroup {
13
+ private mx10: MX10;
14
+
15
+ public readonly onModulePowerInfo = new Subject<ModulePowerInfoData>();
16
+
17
+ constructor(mx10: MX10) {
18
+ this.mx10 = mx10;
19
+ }
20
+
21
+ parse(
22
+ size: number,
23
+ command: number,
24
+ mode: number,
25
+ nid: number,
26
+ buffer: Buffer,
27
+ ) {
28
+ switch (command) {
29
+ case 0x00:
30
+ this.parseModulePowerInfo(size, mode, nid, buffer);
31
+ break;
32
+ }
33
+ }
34
+
35
+ // 0x18.0x00
36
+ private parseModulePowerInfo(
37
+ size: number,
38
+ mode: number,
39
+ nid: number,
40
+ buffer: Buffer,
41
+ ) {
42
+ if (this.onModulePowerInfo.observed) {
43
+ const deviceNID = buffer.readUInt16LE(0);
44
+ const port1 = buffer.readUInt16LE(2);
45
+ const port1Voltage = buffer.readUInt16LE(4);
46
+ const port1Amperage = buffer.readUInt16LE(6);
47
+ const port2 = buffer.readUInt16LE(8);
48
+ const port2Voltage = buffer.readUInt16LE(10);
49
+ const port2Amperage = buffer.readUInt16LE(12);
50
+ const amperage32V = buffer.readUInt16LE(14);
51
+ const amperage12V = buffer.readUInt16LE(16);
52
+ const voltageTotal = buffer.readUInt16LE(18);
53
+ const temperature = buffer.readUInt16LE(20);
54
+
55
+ const port1Status = this.parsePortStatus(port1);
56
+ const port2Status = this.parsePortStatus(port2);
57
+
58
+ this.onModulePowerInfo.next({
59
+ deviceNID,
60
+ port1Status,
61
+ port1Voltage,
62
+ port1Amperage,
63
+ port2Status,
64
+ port2Voltage,
65
+ port2Amperage,
66
+ amperage32V,
67
+ amperage12V,
68
+ voltageTotal,
69
+ temperature,
70
+ });
71
+ }
72
+ }
73
+
74
+ private parsePortStatus(state: number) {
75
+ const offBites = 0b0000000000001;
76
+
77
+ const off = (state & offBites) === 1;
78
+ const tmp = (state >> 4) & 0x0f;
79
+
80
+ if (off) {
81
+ return TrackMode.OFF;
82
+ } else {
83
+ return tmp as TrackMode;
84
+ }
85
+ }
86
+ }
@@ -0,0 +1,70 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-vars */
2
+
3
+ // 0x1A
4
+ import MX10 from '../MX10';
5
+ import {Subject} from 'rxjs';
6
+
7
+ /**
8
+ *
9
+ * @category Groups
10
+ */
11
+ export default class LanNetworkGroup {
12
+ private mx10: MX10;
13
+
14
+ public readonly onPortOpen = new Subject<boolean>();
15
+
16
+ constructor(mx10: MX10) {
17
+ this.mx10 = mx10;
18
+ }
19
+
20
+ portOpen() {
21
+ this.mx10.sendData(
22
+ 0x1a,
23
+ 0x06,
24
+ [
25
+ {value: 1, length: 4},
26
+ {value: 214748364, length: 4},
27
+ {value: 'ZIMO APP', length: 20},
28
+ ],
29
+ 0b01,
30
+ this.mx10.myNID,
31
+ true,
32
+ );
33
+ }
34
+
35
+ // Responses
36
+ parse(
37
+ size: number,
38
+ command: number,
39
+ mode: number,
40
+ nid: number,
41
+ buffer: Buffer,
42
+ ) {
43
+ switch (command) {
44
+ case 0x06:
45
+ this.parsePortOpen(size, mode, nid, buffer);
46
+ break;
47
+ case 0x0e:
48
+ this.parseUnknownCommand(size, mode, nid, buffer);
49
+ break;
50
+ default:
51
+ // eslint-disable-next-line no-console
52
+ console.warn('command not parsed: ' + command.toString());
53
+ }
54
+ }
55
+
56
+ parsePortOpen(size: number, mode: number, nid: number, buffer: Buffer) {
57
+ if (this.onPortOpen.observed) {
58
+ this.mx10.mx10NID = nid;
59
+ this.mx10.connected = true;
60
+
61
+ this.onPortOpen.next(true);
62
+ }
63
+ }
64
+
65
+ // 0x1A.0x0e
66
+ parseUnknownCommand(size: number, mode: number, nid: number, buffer: Buffer) {
67
+ // TODO implement once documented
68
+ // console.debug('IMPLEMENT 0x1A.0x0e', size, mode, nid, buffer);
69
+ }
70
+ }
@@ -0,0 +1,25 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-vars */
2
+ import MX10 from '../MX10';
3
+ import {Buffer} from 'buffer';
4
+
5
+ /**
6
+ *
7
+ * @category Groups
8
+ */
9
+ export default class LanZimoProgrammableScriptGroup {
10
+ private mx10: MX10;
11
+
12
+ constructor(mx10: MX10) {
13
+ this.mx10 = mx10;
14
+ }
15
+
16
+ parse(
17
+ size: number,
18
+ command: number,
19
+ mode: number,
20
+ nid: number,
21
+ buffer: Buffer,
22
+ ) {
23
+ // console.log('parse data group');
24
+ }
25
+ }
@@ -0,0 +1,71 @@
1
+ // 0x0A
2
+ import MX10 from '../MX10';
3
+ import {Buffer} from 'buffer';
4
+
5
+ /**
6
+ *
7
+ * @category Groups
8
+ */
9
+ export default class NetworkGroup {
10
+ private mx10: MX10;
11
+
12
+ constructor(mx10: MX10) {
13
+ this.mx10 = mx10;
14
+ }
15
+
16
+ ping(mode = 0b10) {
17
+ this.mx10.sendData(
18
+ 0x0a,
19
+ 0x00,
20
+ [
21
+ {
22
+ value: this.mx10.mx10NID,
23
+ length: 2,
24
+ },
25
+ ],
26
+ mode,
27
+ );
28
+ }
29
+
30
+ portClose() {
31
+ this.mx10.sendData(0x0a, 0x07, [{value: this.mx10.myNID, length: 2}], 0b01);
32
+ }
33
+
34
+ parse(
35
+ size: number,
36
+ command: number,
37
+ mode: number,
38
+ nid: number,
39
+ buffer: Buffer,
40
+ ) {
41
+ switch (command) {
42
+ case 0x00:
43
+ this.pingResponse(size, mode, nid, buffer);
44
+ break;
45
+ }
46
+ }
47
+
48
+ // 0x0A.0x00
49
+ pingResponse(size: number, mode: number, nid: number, _buffer: Buffer) {
50
+ if (size === 8) {
51
+ // TODO IMPLEMENT DETAIL READOUT
52
+
53
+ if (!this.mx10.mx10NID) {
54
+ this.mx10.mx10NID = nid;
55
+ }
56
+ this.mx10.connected = true;
57
+
58
+ // TODO reconnect when uuid has changed
59
+ // const uuid = buffer.readUInt32LE(0);
60
+
61
+ this.mx10.reconnectLogic();
62
+ } else {
63
+ //Error
64
+
65
+ throw new Error(
66
+ 'LENGTH ERROR: readCmdGrp_0x0A-0x0A, read length as: ' +
67
+ size.toString(),
68
+ );
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,25 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-vars */
2
+ import MX10 from '../MX10';
3
+ import {Buffer} from 'buffer';
4
+
5
+ /**
6
+ *
7
+ * @category Groups
8
+ */
9
+ export default class PropertyConfigGroup {
10
+ private mx10: MX10;
11
+
12
+ constructor(mx10: MX10) {
13
+ this.mx10 = mx10;
14
+ }
15
+
16
+ parse(
17
+ size: number,
18
+ command: number,
19
+ mode: number,
20
+ nid: number,
21
+ buffer: Buffer,
22
+ ) {
23
+ // console.log('parse property config group');
24
+ }
25
+ }
@@ -0,0 +1,25 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-vars */
2
+ import {Buffer} from 'buffer';
3
+ import MX10 from '../MX10';
4
+
5
+ /**
6
+ *
7
+ * @category Groups
8
+ */
9
+ export default class RailwayControlGroup {
10
+ private mx10: MX10;
11
+
12
+ constructor(mx10: MX10) {
13
+ this.mx10 = mx10;
14
+ }
15
+
16
+ parse(
17
+ size: number,
18
+ command: number,
19
+ mode: number,
20
+ nid: number,
21
+ buffer: Buffer,
22
+ ) {
23
+ // console.log('parse railway control group');
24
+ }
25
+ }