@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.
- package/.dockerignore +7 -0
- package/.editorconfig +15 -0
- package/.eslintignore +7 -0
- package/.eslintrc.cjs +17 -0
- package/.gitattributes +1 -0
- package/.github/workflows/docs.yml +46 -0
- package/.github/workflows/library.yml +59 -0
- package/.nvmrc +1 -0
- package/.prettierignore +14 -0
- package/.prettierrc.json +8 -0
- package/LICENSE.md +21 -0
- package/README.md +8 -0
- package/__tests__/connection.test.ts +58 -0
- package/__tests__/dataGroup.test.ts +98 -0
- package/__tests__/infoGroup.test.ts +30 -0
- package/__tests__/lanDataGroup.test.ts +82 -0
- package/__tests__/lanInfoGroup.test.ts +41 -0
- package/__tests__/systemControlGroup.test.ts +42 -0
- package/__tests__/trackCfgGroup.test.ts +43 -0
- package/__tests__/util/index.ts +14 -0
- package/__tests__/vehicleGroup.test.ts +128 -0
- package/dist/@types/communication.d.ts +30 -0
- package/dist/@types/communication.js +2 -0
- package/dist/@types/communication.js.map +1 -0
- package/dist/@types/models.d.ts +172 -0
- package/dist/@types/models.js +2 -0
- package/dist/@types/models.js.map +1 -0
- package/dist/MX10.d.ts +45 -0
- package/dist/MX10.js +233 -0
- package/dist/MX10.js.map +1 -0
- package/dist/docs_entrypoint.d.ts +6 -0
- package/dist/docs_entrypoint.js +7 -0
- package/dist/docs_entrypoint.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/bites.d.ts +9 -0
- package/dist/internal/bites.js +10 -0
- package/dist/internal/bites.js.map +1 -0
- package/dist/internal/speedUtils.d.ts +9 -0
- package/dist/internal/speedUtils.js +29 -0
- package/dist/internal/speedUtils.js.map +1 -0
- package/dist/internal/utils.d.ts +1 -0
- package/dist/internal/utils.js +4 -0
- package/dist/internal/utils.js.map +1 -0
- package/dist/util/enums.d.ts +113 -0
- package/dist/util/enums.js +137 -0
- package/dist/util/enums.js.map +1 -0
- package/dist/util/extended-ascii.d.ts +7 -0
- package/dist/util/extended-ascii.js +162 -0
- package/dist/util/extended-ascii.js.map +1 -0
- package/dist/zcan/accessoryCommandGroup.d.ts +6 -0
- package/dist/zcan/accessoryCommandGroup.js +9 -0
- package/dist/zcan/accessoryCommandGroup.js.map +1 -0
- package/dist/zcan/dataGroup.d.ts +31 -0
- package/dist/zcan/dataGroup.js +233 -0
- package/dist/zcan/dataGroup.js.map +1 -0
- package/dist/zcan/fileControlGroup.d.ts +7 -0
- package/dist/zcan/fileControlGroup.js +9 -0
- package/dist/zcan/fileControlGroup.js.map +1 -0
- package/dist/zcan/fileTransferGroup.d.ts +7 -0
- package/dist/zcan/fileTransferGroup.js +9 -0
- package/dist/zcan/fileTransferGroup.js.map +1 -0
- package/dist/zcan/index.d.ts +18 -0
- package/dist/zcan/index.js +19 -0
- package/dist/zcan/index.js.map +1 -0
- package/dist/zcan/infoGroup.d.ts +15 -0
- package/dist/zcan/infoGroup.js +64 -0
- package/dist/zcan/infoGroup.js.map +1 -0
- package/dist/zcan/lanDataGroup.d.ts +23 -0
- package/dist/zcan/lanDataGroup.js +226 -0
- package/dist/zcan/lanDataGroup.js.map +1 -0
- package/dist/zcan/lanInfoGroup.d.ts +11 -0
- package/dist/zcan/lanInfoGroup.js +58 -0
- package/dist/zcan/lanInfoGroup.js.map +1 -0
- package/dist/zcan/lanNetworkGroup.d.ts +11 -0
- package/dist/zcan/lanNetworkGroup.js +37 -0
- package/dist/zcan/lanNetworkGroup.js.map +1 -0
- package/dist/zcan/lanZimoProgrammableScriptGroup.d.ts +7 -0
- package/dist/zcan/lanZimoProgrammableScriptGroup.js +9 -0
- package/dist/zcan/lanZimoProgrammableScriptGroup.js.map +1 -0
- package/dist/zcan/networkGroup.d.ts +10 -0
- package/dist/zcan/networkGroup.js +38 -0
- package/dist/zcan/networkGroup.js.map +1 -0
- package/dist/zcan/propertyConfigGroup.d.ts +7 -0
- package/dist/zcan/propertyConfigGroup.js +9 -0
- package/dist/zcan/propertyConfigGroup.js.map +1 -0
- package/dist/zcan/railwayControlGroup.d.ts +7 -0
- package/dist/zcan/railwayControlGroup.js +9 -0
- package/dist/zcan/railwayControlGroup.js.map +1 -0
- package/dist/zcan/systemControlGroup.d.ts +13 -0
- package/dist/zcan/systemControlGroup.js +35 -0
- package/dist/zcan/systemControlGroup.js.map +1 -0
- package/dist/zcan/trackCfgGroup.d.ts +16 -0
- package/dist/zcan/trackCfgGroup.js +77 -0
- package/dist/zcan/trackCfgGroup.js.map +1 -0
- package/dist/zcan/trainControlGroup.d.ts +8 -0
- package/dist/zcan/trainControlGroup.js +19 -0
- package/dist/zcan/trainControlGroup.js.map +1 -0
- package/dist/zcan/vehicleGroup.d.ts +26 -0
- package/dist/zcan/vehicleGroup.js +145 -0
- package/dist/zcan/vehicleGroup.js.map +1 -0
- package/dist/zcan/zimoProgrammableScriptGroup.d.ts +7 -0
- package/dist/zcan/zimoProgrammableScriptGroup.js +9 -0
- package/dist/zcan/zimoProgrammableScriptGroup.js.map +1 -0
- package/gulpfile.js +37 -0
- package/jest.config.js +26 -0
- package/package.json +50 -0
- package/protocol_docs/README.md +41 -0
- package/protocol_docs/babel.config.js +3 -0
- package/protocol_docs/docs/command-groups/_category_.json +4 -0
- package/protocol_docs/docs/command-groups/accessories/_category_.json +4 -0
- package/protocol_docs/docs/command-groups/accessories/accessory-state.md +7 -0
- package/protocol_docs/docs/command-groups/command-groups.md +50 -0
- package/protocol_docs/docs/command-groups/data/_category_.json +4 -0
- package/protocol_docs/docs/command-groups/data/data-name-extended.md +60 -0
- package/protocol_docs/docs/command-groups/data/group-count.md +52 -0
- package/protocol_docs/docs/command-groups/data/item-fx-info.md +27 -0
- package/protocol_docs/docs/command-groups/data/item-image-config.md +44 -0
- package/protocol_docs/docs/command-groups/data/item-list-by-index.md +45 -0
- package/protocol_docs/docs/command-groups/data/item-list-by-nid.md +43 -0
- package/protocol_docs/docs/command-groups/data/remove-train.md +33 -0
- package/protocol_docs/docs/command-groups/info/_category_.json +4 -0
- package/protocol_docs/docs/command-groups/info/bidi-info.md +34 -0
- package/protocol_docs/docs/command-groups/lan-data/_category_.json +4 -0
- package/protocol_docs/docs/command-groups/lan-data/data-value-extended.md +65 -0
- package/protocol_docs/docs/command-groups/lan-data/loco-gui-extended.md +48 -0
- package/protocol_docs/docs/command-groups/lan-info/_category_.json +4 -0
- package/protocol_docs/docs/command-groups/lan-info/module-power-info.md +26 -0
- package/protocol_docs/docs/command-groups/lan-network/_category_.json +4 -0
- package/protocol_docs/docs/command-groups/lan-network/open-port.md +47 -0
- package/protocol_docs/docs/command-groups/network/_category_.json +4 -0
- package/protocol_docs/docs/command-groups/network/ping.md +49 -0
- package/protocol_docs/docs/command-groups/system/_category_.json +4 -0
- package/protocol_docs/docs/command-groups/system/system-state.md +59 -0
- package/protocol_docs/docs/command-groups/track/_category_.json +4 -0
- package/protocol_docs/docs/command-groups/track/tse-prog-read.md +37 -0
- package/protocol_docs/docs/command-groups/track/tse-prog-write.md +35 -0
- package/protocol_docs/docs/command-groups/train/_category_.json +4 -0
- package/protocol_docs/docs/command-groups/train/train-part-find.md +33 -0
- package/protocol_docs/docs/command-groups/vehicles/_category_.json +4 -0
- package/protocol_docs/docs/command-groups/vehicles/vehicle-function.md +36 -0
- package/protocol_docs/docs/command-groups/vehicles/vehicle-mode.md +143 -0
- package/protocol_docs/docs/command-groups/vehicles/vehicle-special-function-switch.md +35 -0
- package/protocol_docs/docs/command-groups/vehicles/vehicle-speed.md +55 -0
- package/protocol_docs/docs/description.md +4 -0
- package/protocol_docs/docs/introduction/_category_.json +4 -0
- package/protocol_docs/docs/introduction/how-it-works.md +61 -0
- package/protocol_docs/docs/introduction/implementation.md +39 -0
- package/protocol_docs/docs/introduction/interface.md +62 -0
- package/protocol_docs/docs/introduction/introduction.md +82 -0
- package/protocol_docs/docusaurus.config.js +111 -0
- package/protocol_docs/package-lock.json +25611 -0
- package/protocol_docs/package.json +47 -0
- package/protocol_docs/sidebars.js +22 -0
- package/protocol_docs/src/components/CommandAndGroup/index.tsx +16 -0
- package/protocol_docs/src/components/CommandAndGroup/styles.module.css +12 -0
- package/protocol_docs/src/components/HomepageFeatures/index.tsx +70 -0
- package/protocol_docs/src/components/HomepageFeatures/styles.module.css +11 -0
- package/protocol_docs/src/css/custom.css +76 -0
- package/protocol_docs/src/pages/index.module.css +23 -0
- package/protocol_docs/src/pages/index.tsx +41 -0
- package/protocol_docs/src/pages/markdown-page.md +7 -0
- package/protocol_docs/static/.nojekyll +0 -0
- package/protocol_docs/static/img/docusaurus.png +0 -0
- package/protocol_docs/static/img/favicon.ico +0 -0
- package/protocol_docs/static/img/undraw_docusaurus_mountain.svg +171 -0
- package/protocol_docs/static/img/undraw_docusaurus_react.svg +170 -0
- package/protocol_docs/static/img/undraw_docusaurus_tree.svg +40 -0
- package/protocol_docs/static/typedoc/index.html +10 -0
- package/protocol_docs/tsconfig.json +7 -0
- package/src/@types/communication.ts +73 -0
- package/src/@types/models.ts +215 -0
- package/src/MX10.ts +351 -0
- package/src/docs_entrypoint.ts +34 -0
- package/src/index.ts +8 -0
- package/src/internal/bites.ts +11 -0
- package/src/internal/speedUtils.ts +36 -0
- package/src/internal/utils.ts +3 -0
- package/src/util/enums.ts +147 -0
- package/src/util/extended-ascii.ts +179 -0
- package/src/zcan/accessoryCommandGroup.ts +24 -0
- package/src/zcan/dataGroup.ts +342 -0
- package/src/zcan/fileControlGroup.ts +25 -0
- package/src/zcan/fileTransferGroup.ts +25 -0
- package/src/zcan/index.ts +37 -0
- package/src/zcan/infoGroup.ts +90 -0
- package/src/zcan/lanDataGroup.ts +361 -0
- package/src/zcan/lanInfoGroup.ts +86 -0
- package/src/zcan/lanNetworkGroup.ts +70 -0
- package/src/zcan/lanZimoProgrammableScriptGroup.ts +25 -0
- package/src/zcan/networkGroup.ts +71 -0
- package/src/zcan/propertyConfigGroup.ts +25 -0
- package/src/zcan/railwayControlGroup.ts +25 -0
- package/src/zcan/systemControlGroup.ts +62 -0
- package/src/zcan/trackCfgGroup.ts +109 -0
- package/src/zcan/trainControlGroup.ts +48 -0
- package/src/zcan/vehicleGroup.ts +267 -0
- package/src/zcan/zimoProgrammableScriptGroup.ts +25 -0
- package/tsconfig.build.json +12 -0
- package/tsconfig.json +49 -0
- 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
|
+
}
|