@zimo-elektronik/zcan 1.0.40 → 1.0.42
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/__tests__/connection.test.ts +1 -1
- package/dist/MX10.d.ts +3 -2
- package/dist/MX10.js +9 -8
- package/dist/MX10.js.map +1 -1
- package/dist/data/dataGroup.d.ts +5 -4
- package/dist/data/dataGroup.js +103 -20
- package/dist/data/dataGroup.js.map +1 -1
- package/dist/data/dataMsg.d.ts +1 -2
- package/dist/data/dataMsg.js +4 -7
- package/dist/data/dataMsg.js.map +1 -1
- package/dist/data/lanDataGroup.d.ts +5 -3
- package/dist/data/lanDataGroup.js +35 -26
- package/dist/data/lanDataGroup.js.map +1 -1
- package/dist/data/lanDataMsg.d.ts +26 -0
- package/dist/data/lanDataMsg.js +57 -0
- package/dist/data/lanDataMsg.js.map +1 -0
- package/dist/info/infoGroup.js +6 -6
- package/dist/info/infoGroup.js.map +1 -1
- package/dist/loco/vehicleGroup.js +21 -21
- package/dist/loco/vehicleGroup.js.map +1 -1
- package/dist/network/lanNetworkGroup.js +6 -6
- package/dist/network/lanNetworkGroup.js.map +1 -1
- package/dist/network/networkGroup.js +1 -1
- package/dist/network/networkGroup.js.map +1 -1
- package/dist/track/trackGroup.js +9 -9
- package/dist/track/trackGroup.js.map +1 -1
- package/package.json +1 -1
- package/src/MX10.ts +13 -13
- package/src/data/dataGroup.ts +114 -21
- package/src/data/dataMsg.ts +59 -60
- package/src/data/lanDataGroup.ts +69 -33
- package/src/data/lanDataMsg.ts +71 -0
- package/src/file/fileControlGroup.ts +1 -1
- package/src/file/fileTransferGroup.ts +1 -1
- package/src/info/infoGroup.ts +7 -8
- package/src/loco/vehicleGroup.ts +25 -25
- package/src/misc/propertyConfigGroup.ts +1 -1
- package/src/misc/railwayControlGroup.ts +1 -1
- package/src/network/lanNetworkGroup.ts +6 -6
- package/src/network/networkGroup.ts +6 -7
- package/src/script/lanScriptGroup.ts +1 -1
- package/src/script/scriptGroup.ts +1 -1
- package/src/track/trackGroup.ts +14 -14
package/src/MX10.ts
CHANGED
|
@@ -58,8 +58,9 @@ export default class MX10
|
|
|
58
58
|
readonly lanNetwork = new LanNetworkGroup(this);
|
|
59
59
|
readonly lanZimoProgrammableScript = new LanZimoProgrammableScriptGroup(this);
|
|
60
60
|
|
|
61
|
-
readonly
|
|
62
|
-
readonly
|
|
61
|
+
readonly logError = new Subject<string>();
|
|
62
|
+
readonly logWarning = new Subject<string>();
|
|
63
|
+
readonly logInfo = new Subject<string>();
|
|
63
64
|
readonly connectionTimeout: number;
|
|
64
65
|
|
|
65
66
|
private mx10Socket: Socket | null = null;
|
|
@@ -141,8 +142,7 @@ export default class MX10
|
|
|
141
142
|
if (this.interval === undefined) {
|
|
142
143
|
this.interval = setInterval(() => {
|
|
143
144
|
if (!this.connected) {
|
|
144
|
-
|
|
145
|
-
console.log('Reconnecting...');
|
|
145
|
+
this.logInfo.next('Reconnecting...');
|
|
146
146
|
this.network.portClose();
|
|
147
147
|
this.connected = false;
|
|
148
148
|
this.mx10NID = 0;
|
|
@@ -171,14 +171,14 @@ export default class MX10
|
|
|
171
171
|
sendMsg(msg: Message, force = false)
|
|
172
172
|
{
|
|
173
173
|
const buffer = msg.udp(this.myNID);
|
|
174
|
-
this.
|
|
174
|
+
this.logInfo.next("mx10.sendMsg: " + JSON.stringify(buffer));
|
|
175
175
|
this.send(buffer, force);
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
sendData(group: number, cmd: number, data: ZcanDataArray = [], mode = MsgMode.CMD, nid = this.myNID, force = false)
|
|
179
179
|
{
|
|
180
180
|
const buffer = this.formatData(group, cmd, mode, nid, data);
|
|
181
|
-
//this.
|
|
181
|
+
//this.logInfo.next("mx10.sendData: " + JSON.stringify(buffer));
|
|
182
182
|
this.send(buffer, force);
|
|
183
183
|
}
|
|
184
184
|
|
|
@@ -230,12 +230,12 @@ export default class MX10
|
|
|
230
230
|
private send(message: Buffer, force = false)
|
|
231
231
|
{
|
|
232
232
|
if(!this.connected && !force) {
|
|
233
|
-
this.
|
|
233
|
+
this.logError.next('mx10.connection.not_connected');
|
|
234
234
|
return;
|
|
235
235
|
}
|
|
236
236
|
this.mx10Socket?.send(message, 0, message.length, this.outgoingPort, this.mx10IP, (err) => {
|
|
237
237
|
if (err && this.debugCommunication)
|
|
238
|
-
this.
|
|
238
|
+
this.logInfo.next(err.message);
|
|
239
239
|
});
|
|
240
240
|
}
|
|
241
241
|
|
|
@@ -249,23 +249,23 @@ export default class MX10
|
|
|
249
249
|
const command = commandAndMode >> 2;
|
|
250
250
|
const mode = commandAndMode & 0x03;
|
|
251
251
|
const nid = message.readUInt16LE(6);
|
|
252
|
-
// this.
|
|
252
|
+
// this.logInfo.next('rx: ' + JSON.stringify(message));
|
|
253
253
|
if(!this.mx10NID && (group !== 0x1a || command !== 0x06 || mode !== MsgMode.ACK))
|
|
254
254
|
return;
|
|
255
255
|
if(this.mx10NID && nid !== this.mx10NID) {
|
|
256
256
|
if((nid >> 8 !== 0xc0)) {
|
|
257
257
|
if(!(group === 0xa && command === 0 && mode === MsgMode.EVT))
|
|
258
|
-
this.
|
|
258
|
+
this.logInfo.next('Not from MX10: ' + JSON.stringify(message));
|
|
259
259
|
}
|
|
260
260
|
// else
|
|
261
|
-
// this.
|
|
261
|
+
// this.logInfo.next('This packet is not from our MX10: ' + JSON.stringify(message));
|
|
262
262
|
return;
|
|
263
263
|
}
|
|
264
264
|
// this.log.next('MX10 >> ' + JSON.stringify(message));
|
|
265
265
|
|
|
266
266
|
const buffer = message.slice(8); //Remove first 8 bytes; left only with data
|
|
267
267
|
|
|
268
|
-
// this.
|
|
268
|
+
// this.logInfo.next(JSON.stringify(message));
|
|
269
269
|
this.printReadout(group, command, mode, nid, size, buffer, false);
|
|
270
270
|
|
|
271
271
|
switch (group) {
|
|
@@ -338,7 +338,7 @@ export default class MX10
|
|
|
338
338
|
const f = (obj: unknown) => Number(obj).toString(16);
|
|
339
339
|
const arrow = '|' + (out ? '→' : '←');
|
|
340
340
|
const msg = `${arrow} g=${f(group)} c=${f(cmd)} m=${f(mode)} n=${f(nid)} l=${f(size,)} : ${data}`;
|
|
341
|
-
this.
|
|
341
|
+
this.logInfo.next(msg);
|
|
342
342
|
}
|
|
343
343
|
}
|
|
344
344
|
}
|
package/src/data/dataGroup.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {RemoveLocomotiveData, DataNameExtended, DataNameValue1,
|
|
|
6
6
|
ItemFxMode, ItemFxConfig, ItemImageData, ItemListByIndexData, ItemListByNidData} from '../common/models';
|
|
7
7
|
import {FxConfigType, FxModeType, ImageType, MsgMode, NameType} from '../common/enums';
|
|
8
8
|
import ExtendedASCII from '../common/extendedAscii';
|
|
9
|
-
import { MsgGroupCount } from './dataMsg';
|
|
9
|
+
import { MsgGroupCount, MsgItemsByIndexReq, MsgItemsByIndexRsp } from './dataMsg';
|
|
10
10
|
import { Query } from '../docs_entrypoint';
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -16,7 +16,7 @@ import { Query } from '../docs_entrypoint';
|
|
|
16
16
|
export default class DataGroup
|
|
17
17
|
{
|
|
18
18
|
public readonly onGroupCount = new Subject<MsgGroupCount>();
|
|
19
|
-
public readonly onListItemsByIndex = new Subject<
|
|
19
|
+
public readonly onListItemsByIndex = new Subject<MsgItemsByIndexRsp>();
|
|
20
20
|
public readonly onListItemsByNID = new Subject<ItemListByNidData>();
|
|
21
21
|
public readonly onRemoveLocomotive = new Subject<RemoveLocomotiveData>();
|
|
22
22
|
public readonly onItemImageConfig = new Subject<ItemImageData>();
|
|
@@ -25,6 +25,7 @@ export default class DataGroup
|
|
|
25
25
|
public readonly onDataNameExtended = new Subject<DataNameExtended>();
|
|
26
26
|
|
|
27
27
|
private groupCountQ: Query<MsgGroupCount> | undefined = undefined;
|
|
28
|
+
private byIndexQ: Query<MsgItemsByIndexRsp> | undefined = undefined;
|
|
28
29
|
|
|
29
30
|
private mx10: MX10;
|
|
30
31
|
|
|
@@ -36,38 +37,128 @@ export default class DataGroup
|
|
|
36
37
|
async groupCount(groupNid = 0): Promise<MsgGroupCount | undefined>
|
|
37
38
|
{
|
|
38
39
|
if(this.groupCountQ !== undefined && !await this.groupCountQ.lock()) {
|
|
39
|
-
this.mx10.
|
|
40
|
+
this.mx10.logInfo.next("mx10.groupCount: failed to acquire lock");
|
|
40
41
|
return undefined;
|
|
41
42
|
}
|
|
42
43
|
this.groupCountQ = new Query(MsgGroupCount.header(MsgMode.REQ, this.mx10.mx10NID), this.onGroupCount);
|
|
43
44
|
this.groupCountQ.log = ((msg) => {
|
|
44
|
-
this.mx10.
|
|
45
|
+
this.mx10.logInfo.next(msg);
|
|
45
46
|
});
|
|
46
47
|
this.groupCountQ.tx = ((header) => {
|
|
47
48
|
const msg = new MsgGroupCount(header, groupNid);
|
|
48
|
-
this.mx10.
|
|
49
|
+
this.mx10.logInfo.next('groupCount query tx: ' + JSON.stringify(msg));
|
|
49
50
|
this.mx10.sendMsg(msg);
|
|
50
51
|
});
|
|
51
52
|
this.groupCountQ.match = ((msg) => {
|
|
52
|
-
this.mx10.
|
|
53
|
+
this.mx10.logInfo.next('groupCount query rx: ' + JSON.stringify(msg));
|
|
53
54
|
return (msg.group() === groupNid);
|
|
54
55
|
})
|
|
55
56
|
const rv = await this.groupCountQ.run();
|
|
56
|
-
this.mx10.
|
|
57
|
+
this.mx10.logInfo.next("mx10.groupCount.rv: " + JSON.stringify(rv));
|
|
57
58
|
this.groupCountQ.unlock();
|
|
58
59
|
this.groupCountQ = undefined;
|
|
59
60
|
return rv;
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
listItemsByIndex(
|
|
63
|
+
async listItemsByIndex(groupNid: number, index: number): Promise<MsgItemsByIndexRsp | undefined>
|
|
63
64
|
{
|
|
64
|
-
this.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
if(this.byIndexQ !== undefined && !await this.byIndexQ.lock()) {
|
|
66
|
+
this.mx10.logInfo.next("mx10.listItemsByIndex: failed to acquire lock");
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
this.byIndexQ = new Query(MsgItemsByIndexReq.header(MsgMode.REQ, this.mx10.mx10NID), this.onListItemsByIndex);
|
|
70
|
+
this.byIndexQ.log = ((msg) => {
|
|
71
|
+
this.mx10.logInfo.next(msg);
|
|
72
|
+
});
|
|
73
|
+
this.byIndexQ.tx = ((header) => {
|
|
74
|
+
const msg = new MsgItemsByIndexReq(header, this.mx10.myNID, groupNid, index);
|
|
75
|
+
this.mx10.logInfo.next('listItemsByIndex query tx: ' + JSON.stringify(msg));
|
|
76
|
+
this.mx10.sendMsg(msg);
|
|
77
|
+
});
|
|
78
|
+
this.byIndexQ.match = ((msg) => {
|
|
79
|
+
this.mx10.logInfo.next('listItemsByIndex query rx: ' + JSON.stringify(msg));
|
|
80
|
+
this.mx10.logInfo.next('listItemsByIndex query rx: ' + msg.itemNid());
|
|
81
|
+
const nid = msg.itemNid();
|
|
82
|
+
switch(groupNid) {
|
|
83
|
+
case 0:
|
|
84
|
+
return nid < 0x2800;
|
|
85
|
+
case 0x2800:
|
|
86
|
+
return nid < 0x28ff;
|
|
87
|
+
case 0x2f00:
|
|
88
|
+
return nid < 0x3000;
|
|
89
|
+
case 0x3000:
|
|
90
|
+
return nid < 0x3200;
|
|
91
|
+
case 0x3200:
|
|
92
|
+
return nid < 0x3a00;
|
|
93
|
+
case 0x3a00:
|
|
94
|
+
return nid < 0x3e00;
|
|
95
|
+
case 0x4000:
|
|
96
|
+
return nid < 0x4400;
|
|
97
|
+
case 0x4400:
|
|
98
|
+
return nid < 0x4600;
|
|
99
|
+
case 0x4600:
|
|
100
|
+
return nid < 0x4800;
|
|
101
|
+
case 0x5000:
|
|
102
|
+
return nid < 0x5040;
|
|
103
|
+
case 0x5040:
|
|
104
|
+
return nid < 0x5080;
|
|
105
|
+
case 0x5080:
|
|
106
|
+
return nid < 0x50c0;
|
|
107
|
+
case 0x50c0:
|
|
108
|
+
return nid < 0x50d0;
|
|
109
|
+
case 0x50d0:
|
|
110
|
+
return nid < 0x50e0;
|
|
111
|
+
case 0x5100:
|
|
112
|
+
return nid < 0x5140;
|
|
113
|
+
case 0x5140:
|
|
114
|
+
return nid < 0x5180;
|
|
115
|
+
case 0x5800:
|
|
116
|
+
return nid < 0x5880;
|
|
117
|
+
case 0x5a00:
|
|
118
|
+
return nid < 0x5b00;
|
|
119
|
+
case 0x6000:
|
|
120
|
+
return nid < 0x6100;
|
|
121
|
+
case 0x6100:
|
|
122
|
+
return nid < 0x6400;
|
|
123
|
+
case 0x6600:
|
|
124
|
+
return nid < 0x6700;
|
|
125
|
+
case 0x8000:
|
|
126
|
+
return nid < 0xc000;
|
|
127
|
+
case 0xc000:
|
|
128
|
+
return nid < 0xc100;
|
|
129
|
+
case 0xc100:
|
|
130
|
+
return nid < 0xc200;
|
|
131
|
+
case 0xc200:
|
|
132
|
+
return nid < 0xc300;
|
|
133
|
+
case 0xc300:
|
|
134
|
+
return nid < 0xc400;
|
|
135
|
+
case 0xc400:
|
|
136
|
+
return nid < 0xc500;
|
|
137
|
+
case 0xd000:
|
|
138
|
+
return nid < 0xe000;
|
|
139
|
+
case 0xe000:
|
|
140
|
+
return nid < 0xf000;
|
|
141
|
+
case 0xf000:
|
|
142
|
+
return nid <= 0xffff;
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
})
|
|
146
|
+
const rv = await this.byIndexQ.run();
|
|
147
|
+
this.mx10.logInfo.next("mx10.listItemsByIndex.rv: " + JSON.stringify(rv));
|
|
148
|
+
this.byIndexQ.unlock();
|
|
149
|
+
this.byIndexQ = undefined;
|
|
150
|
+
return rv;
|
|
69
151
|
}
|
|
70
152
|
|
|
153
|
+
// listItemsByIndex(groupNID: number, index: number)
|
|
154
|
+
// {
|
|
155
|
+
// this.mx10.sendData(0x07, 0x01, [
|
|
156
|
+
// {value: this.mx10.mx10NID, length: 2},
|
|
157
|
+
// {value: groupNID, length: 2},
|
|
158
|
+
// {value: index, length: 2},
|
|
159
|
+
// ], 0b00);
|
|
160
|
+
// }
|
|
161
|
+
|
|
71
162
|
listItemsByNID(searchAfterValue: number)
|
|
72
163
|
{
|
|
73
164
|
this.mx10.sendData(0x07, 0x02, [
|
|
@@ -140,15 +231,15 @@ export default class DataGroup
|
|
|
140
231
|
switch (command)
|
|
141
232
|
{
|
|
142
233
|
case 0x00:
|
|
143
|
-
this.mx10.
|
|
234
|
+
this.mx10.logInfo.next('parseGroupCount: ' + JSON.stringify(buffer));
|
|
144
235
|
this.parseGroupCount(size, mode, nid, buffer);
|
|
145
236
|
break;
|
|
146
237
|
case 0x01:
|
|
147
|
-
this.mx10.
|
|
238
|
+
this.mx10.logInfo.next('parseItemListByIndex: ' + JSON.stringify(buffer));
|
|
148
239
|
this.parseItemListByIndex(size, mode, nid, buffer);
|
|
149
240
|
break;
|
|
150
241
|
case 0x02:
|
|
151
|
-
this.mx10.
|
|
242
|
+
this.mx10.logInfo.next('parseItemListByNid: ' + JSON.stringify(buffer));
|
|
152
243
|
this.parseItemListByNid(size, mode, nid, buffer);
|
|
153
244
|
break;
|
|
154
245
|
case 0x12:
|
|
@@ -167,7 +258,7 @@ export default class DataGroup
|
|
|
167
258
|
this.parseDataNameExtended(size, mode, nid, buffer);
|
|
168
259
|
break;
|
|
169
260
|
default:
|
|
170
|
-
this.mx10.
|
|
261
|
+
this.mx10.logInfo.next('command not parsed: ' + command.toString());
|
|
171
262
|
}
|
|
172
263
|
}
|
|
173
264
|
|
|
@@ -189,8 +280,10 @@ export default class DataGroup
|
|
|
189
280
|
const index = buffer.readUInt16LE(0);
|
|
190
281
|
const deviceNID = buffer.readUInt16LE(2);
|
|
191
282
|
const msSinceLastCommunication = buffer.readUInt16LE(4);
|
|
192
|
-
if(deviceNID)
|
|
193
|
-
|
|
283
|
+
if(!deviceNID)
|
|
284
|
+
return;
|
|
285
|
+
this.onListItemsByIndex.next(new MsgItemsByIndexRsp(MsgItemsByIndexRsp.header(mode, nid),
|
|
286
|
+
index, deviceNID, msSinceLastCommunication));
|
|
194
287
|
}
|
|
195
288
|
|
|
196
289
|
// 0x07.0x02
|
|
@@ -238,7 +331,7 @@ export default class DataGroup
|
|
|
238
331
|
for(let i=0; i<32; i+=2)
|
|
239
332
|
fxMode.push((fxModes>>i)&0b11);
|
|
240
333
|
const msg: ItemFxMode = {nid: NID, group, mode: fxMode};
|
|
241
|
-
this.mx10.
|
|
334
|
+
this.mx10.logInfo.next('parseItemFxMode: ' + JSON.stringify(msg));
|
|
242
335
|
this.onItemFxMode.next(msg);
|
|
243
336
|
}
|
|
244
337
|
|
|
@@ -275,7 +368,7 @@ export default class DataGroup
|
|
|
275
368
|
const item = buffer.readUInt16LE(4);
|
|
276
369
|
const data = buffer.readUInt16LE(6);
|
|
277
370
|
const msg: ItemFxConfig = {nid: NID, function: fx, item, data};
|
|
278
|
-
this.mx10.
|
|
371
|
+
this.mx10.logInfo.next('parseItemFxConfig: ' + JSON.stringify(msg));
|
|
279
372
|
this.onItemFxConfig.next(msg);
|
|
280
373
|
}
|
|
281
374
|
|
package/src/data/dataMsg.ts
CHANGED
|
@@ -5,87 +5,86 @@ import { MsgMode } from "../common/enums";
|
|
|
5
5
|
|
|
6
6
|
export class MsgGroupCount extends Message
|
|
7
7
|
{
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
public static header(mode: MsgMode, nid: number): Header
|
|
9
|
+
{return {group: 0x7, cmd: 0x0, mode: mode, nid: nid}}
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
constructor(header: Header, group?: number, count?: number)
|
|
12
|
+
{
|
|
13
|
+
super(header);
|
|
14
|
+
if(group !== undefined)
|
|
15
|
+
super.push({value: group, length: 2});
|
|
16
|
+
// super.push({value: groupNid, length: 2});
|
|
17
|
+
if(count !== undefined)
|
|
18
|
+
super.push({value: count, length: 2});
|
|
19
|
+
}
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
group() {return this.data.length ? this.data[0].value as number : this.header.nid;}
|
|
22
|
+
count() {return this.data.length > 1 ? this.data[1].value as number : 0;}
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
export class MsgItemsByIndexReq extends Message
|
|
27
27
|
{
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
public static header(mode: MsgMode, nid: number): Header
|
|
29
|
+
{return {group: 0x7, cmd: 0x1, mode: mode, nid: nid}}
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
constructor(header: Header, mx10Nid: number, groupNid: number, index: number)
|
|
32
|
+
{
|
|
33
|
+
super(header);
|
|
34
|
+
// super.push({value: mx10Nid, length: 2});
|
|
35
|
+
super.push({value: groupNid, length: 2});
|
|
36
|
+
super.push({value: index, length: 2});
|
|
37
|
+
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
export class MsgItemsByIndexRsp extends Message
|
|
41
41
|
{
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
public static header(mode: MsgMode, nid: number): Header
|
|
43
|
+
{return {group: 0x7, cmd: 0x1, mode: mode, nid: nid}}
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
lastTick(): number {return (this.data[4].value as number)}
|
|
45
|
+
constructor(header: Header, index: number, itemNid: number, lastTick: number)
|
|
46
|
+
{
|
|
47
|
+
super(header);
|
|
48
|
+
super.push({value: index, length: 2});
|
|
49
|
+
super.push({value: itemNid, length: 2});
|
|
50
|
+
if(lastTick !== undefined)
|
|
51
|
+
super.push({value: lastTick, length: 2});
|
|
52
|
+
}
|
|
53
|
+
index(): number {return (this.data[0].value as number)}
|
|
54
|
+
itemNid(): number {return (this.data[1].value as number)}
|
|
55
|
+
lastTick(): number {return (this.data[2].value as number)}
|
|
56
|
+
// lastTick(): number {return this.data.length > 4 ? (this.data[4].value as number) : 0}
|
|
58
57
|
}
|
|
59
58
|
|
|
60
59
|
export class MsgItemsByNidReq extends Message
|
|
61
60
|
{
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
public static header(mode: MsgMode, nid: number): Header
|
|
62
|
+
{return {group: 0x7, cmd: 0x2, mode: mode, nid: nid}}
|
|
64
63
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
constructor(header: Header, mx10Nid: number, precedingNid: number)
|
|
65
|
+
{
|
|
66
|
+
super(header);
|
|
67
|
+
super.push({value: mx10Nid, length: 2});
|
|
68
|
+
super.push({value: precedingNid, length: 2});
|
|
69
|
+
}
|
|
71
70
|
}
|
|
72
71
|
|
|
73
72
|
export class MsgItemsByNidRsp extends Message
|
|
74
73
|
{
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
public static header(mode: MsgMode, nid: number): Header
|
|
75
|
+
{return {group: 0x7, cmd: 0x2, mode: mode, nid: nid}}
|
|
77
76
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
77
|
+
constructor(header: Header, itemNid: number, index: number, itemState: number, lastTick: number | undefined)
|
|
78
|
+
{
|
|
79
|
+
super(header);
|
|
80
|
+
super.push({value: itemNid, length: 2});
|
|
81
|
+
super.push({value: index, length: 2});
|
|
82
|
+
super.push({value: itemState, length: 2});
|
|
83
|
+
if(lastTick !== undefined)
|
|
84
|
+
super.push({value: lastTick, length: 2});
|
|
85
|
+
}
|
|
86
|
+
itemNid(): number {return (this.data[1].value as number)}
|
|
87
|
+
index(): number {return (this.data[2].value as number)}
|
|
88
|
+
itemState(): number {return (this.data[3].value as number)}
|
|
89
|
+
lastTick(): number {return (this.data[4].value as number)}
|
|
91
90
|
}
|
package/src/data/lanDataGroup.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
// 0x17
|
|
2
2
|
import MX10 from '../MX10';
|
|
3
|
-
import {FunctionMode, FxConfigType, getOperatingMode, OperatingMode} from '../common/enums';
|
|
3
|
+
import {FunctionMode, FxConfigType, getOperatingMode, MsgMode, OperatingMode} from '../common/enums';
|
|
4
4
|
import {DataNameExtendedData, DataValueExtendedData, LocoGuiMXExtended, LocoSpeedTabExtended, SpeedTabData,
|
|
5
5
|
Train, TrainFlags, TrainFunction} from '../common/models';
|
|
6
6
|
import {Subject} from 'rxjs';
|
|
7
7
|
import {parseSpeed} from '../common/speedUtils';
|
|
8
8
|
import ExtendedASCII from '../common/extendedAscii';
|
|
9
9
|
import {manualModeB, shuntingFunctionB} from '../common/bites';
|
|
10
|
-
import {ZcanDataArray} from '../common/communication';
|
|
10
|
+
import {Query, ZcanDataArray} from '../common/communication';
|
|
11
|
+
import { MsgLocoGuiReq, MsgLocoGuiRsp } from './lanDataMsg';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
*
|
|
@@ -15,12 +16,14 @@ import {ZcanDataArray} from '../common/communication';
|
|
|
15
16
|
*/
|
|
16
17
|
export default class LanDataGroup
|
|
17
18
|
{
|
|
18
|
-
public readonly onLocoGuiExtended = new Subject<
|
|
19
|
+
public readonly onLocoGuiExtended = new Subject<MsgLocoGuiRsp>();
|
|
19
20
|
public readonly onLocoGuiMXExtended = new Subject<LocoGuiMXExtended>();
|
|
20
21
|
public readonly onDataValueExtended = new Subject<DataValueExtendedData>();
|
|
21
22
|
public readonly onDataNameExtended = new Subject<DataNameExtendedData>();
|
|
22
23
|
public readonly onLocoSpeedTabExtended = new Subject<LocoSpeedTabExtended>();
|
|
23
24
|
|
|
25
|
+
private locoGuiQ: Query<MsgLocoGuiRsp> | undefined = undefined;
|
|
26
|
+
|
|
24
27
|
private mx10: MX10;
|
|
25
28
|
|
|
26
29
|
constructor(mx10: MX10)
|
|
@@ -79,15 +82,41 @@ export default class LanDataGroup
|
|
|
79
82
|
]);
|
|
80
83
|
}
|
|
81
84
|
|
|
82
|
-
locoGuiExtended(
|
|
85
|
+
async locoGuiExtended(nid: number): Promise<MsgLocoGuiRsp | undefined>
|
|
83
86
|
{
|
|
84
|
-
this.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
if(this.locoGuiQ !== undefined && !await this.locoGuiQ.lock()) {
|
|
88
|
+
this.mx10.logInfo.next("mx10.locoGuiExtended: failed to acquire lock");
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
this.locoGuiQ = new Query(MsgLocoGuiReq.header(MsgMode.REQ, this.mx10.mx10NID), this.onLocoGuiExtended);
|
|
92
|
+
this.locoGuiQ.log = ((msg) => {
|
|
93
|
+
this.mx10.logInfo.next(msg);
|
|
94
|
+
});
|
|
95
|
+
this.locoGuiQ.tx = ((header) => {
|
|
96
|
+
const msg = new MsgLocoGuiReq(header, nid, 0);
|
|
97
|
+
this.mx10.logInfo.next('locoGuiExtended query tx: ' + JSON.stringify(msg));
|
|
98
|
+
this.mx10.sendMsg(msg);
|
|
99
|
+
});
|
|
100
|
+
this.locoGuiQ.match = ((msg) => {
|
|
101
|
+
this.mx10.logInfo.next('locoGuiExtended query rx: ' + JSON.stringify(msg));
|
|
102
|
+
return (msg.locoNid() === nid);
|
|
103
|
+
})
|
|
104
|
+
const rv = await this.locoGuiQ.run();
|
|
105
|
+
this.mx10.logInfo.next("mx10.locoGuiExtended.rv: " + JSON.stringify(rv));
|
|
106
|
+
this.locoGuiQ.unlock();
|
|
107
|
+
this.locoGuiQ = undefined;
|
|
108
|
+
return rv;
|
|
89
109
|
}
|
|
90
110
|
|
|
111
|
+
// locoGuiExtended(NID: number)
|
|
112
|
+
// {
|
|
113
|
+
// this.mx10.sendData(0x17, 0x27, [
|
|
114
|
+
// {value: this.mx10.mx10NID, length: 2},
|
|
115
|
+
// {value: NID, length: 2},
|
|
116
|
+
// {value: 0, length: 2},
|
|
117
|
+
// ], 0b00);
|
|
118
|
+
// }
|
|
119
|
+
|
|
91
120
|
locoGuiMXExtended(NID: number)
|
|
92
121
|
{
|
|
93
122
|
this.mx10.sendData(0x17,0x28, [
|
|
@@ -201,25 +230,35 @@ export default class LanDataGroup
|
|
|
201
230
|
const driveType = buffer.readUInt16LE(48);
|
|
202
231
|
const era = buffer.readUInt16LE(50);
|
|
203
232
|
const countryCode = buffer.readUInt16LE(52);
|
|
204
|
-
|
|
205
|
-
// reading 64 bytes of functions
|
|
206
|
-
const functions = Array<TrainFunction>();
|
|
233
|
+
const functions: number[] = [];
|
|
207
234
|
for (let i = 0; i < 32; i++) {
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
icon === 0 ? String(i).padStart(2, '0') : String(icon);
|
|
211
|
-
functions.push({
|
|
212
|
-
mode: FunctionMode.switch,
|
|
213
|
-
active: false,
|
|
214
|
-
icon: iconString.padStart(4, icon === 0 ? '07' : '0'),
|
|
215
|
-
});
|
|
235
|
+
const fun = buffer.readUInt16LE(54 + 2*i);
|
|
236
|
+
functions.push(fun);
|
|
216
237
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
238
|
+
|
|
239
|
+
const msg = new MsgLocoGuiRsp(MsgLocoGuiRsp.header(mode, nid), NID, SubID, vehicleGroup, name, imageId, tacho, speedFwd, speedRev, speedRange,
|
|
240
|
+
driveType, era, countryCode, functions);
|
|
241
|
+
|
|
242
|
+
this.onLocoGuiExtended.next(msg);
|
|
243
|
+
|
|
244
|
+
// // reading 64 bytes of functions
|
|
245
|
+
// const functions = Array<TrainFunction>();
|
|
246
|
+
// for (let i = 0; i < 32; i++) {
|
|
247
|
+
// const icon = buffer.readUInt16LE(54 + i * 2);
|
|
248
|
+
// const iconString =
|
|
249
|
+
// icon === 0 ? String(i).padStart(2, '0') : String(icon);
|
|
250
|
+
// functions.push({
|
|
251
|
+
// mode: FunctionMode.switch,
|
|
252
|
+
// active: false,
|
|
253
|
+
// icon: iconString.padStart(4, icon === 0 ? '07' : '0'),
|
|
254
|
+
// });
|
|
255
|
+
// }
|
|
256
|
+
// this.onLocoGuiExtended.next({nid: NID, subId: SubID, name: name, group: vehicleGroup,
|
|
257
|
+
// image: imageId == 0 ? undefined : imageId.toString(), tacho: tacho.toString(),
|
|
258
|
+
// speedFwd: speedFwd, speedRev: speedRev, speedRange: speedRange,
|
|
259
|
+
// operatingMode: OperatingMode.UNKNOWN, driveType: driveType, era: this.parseEra(era),
|
|
260
|
+
// countryCode: countryCode, functions,
|
|
261
|
+
// });
|
|
223
262
|
}
|
|
224
263
|
|
|
225
264
|
// 0x17.0x28
|
|
@@ -248,14 +287,11 @@ export default class LanDataGroup
|
|
|
248
287
|
|
|
249
288
|
// reading 64 bytes of functions
|
|
250
289
|
const functions = Array<TrainFunction>();
|
|
251
|
-
for (let i = 0; i <
|
|
290
|
+
for (let i = 0; i < 64; i++) {
|
|
252
291
|
const icon = buffer.readUInt16LE(68 + i * 2);
|
|
253
|
-
const
|
|
254
|
-
|
|
255
|
-
functions.push({
|
|
256
|
-
mode: FunctionMode.switch,
|
|
257
|
-
active: false,
|
|
258
|
-
icon: iconString.padStart(4, icon === 0 ? '07' : '0'),
|
|
292
|
+
const fxMode = buffer.readUInt16LE(196 + i * 2) as FunctionMode;
|
|
293
|
+
const iconString = icon === 0 ? String(i).padStart(2, '0') : String(icon);
|
|
294
|
+
functions.push({mode: fxMode, active: false, icon: iconString.padStart(4, icon === 0 ? '07' : '0'),
|
|
259
295
|
});
|
|
260
296
|
}
|
|
261
297
|
|