@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.
Files changed (43) hide show
  1. package/__tests__/connection.test.ts +1 -1
  2. package/dist/MX10.d.ts +3 -2
  3. package/dist/MX10.js +9 -8
  4. package/dist/MX10.js.map +1 -1
  5. package/dist/data/dataGroup.d.ts +5 -4
  6. package/dist/data/dataGroup.js +103 -20
  7. package/dist/data/dataGroup.js.map +1 -1
  8. package/dist/data/dataMsg.d.ts +1 -2
  9. package/dist/data/dataMsg.js +4 -7
  10. package/dist/data/dataMsg.js.map +1 -1
  11. package/dist/data/lanDataGroup.d.ts +5 -3
  12. package/dist/data/lanDataGroup.js +35 -26
  13. package/dist/data/lanDataGroup.js.map +1 -1
  14. package/dist/data/lanDataMsg.d.ts +26 -0
  15. package/dist/data/lanDataMsg.js +57 -0
  16. package/dist/data/lanDataMsg.js.map +1 -0
  17. package/dist/info/infoGroup.js +6 -6
  18. package/dist/info/infoGroup.js.map +1 -1
  19. package/dist/loco/vehicleGroup.js +21 -21
  20. package/dist/loco/vehicleGroup.js.map +1 -1
  21. package/dist/network/lanNetworkGroup.js +6 -6
  22. package/dist/network/lanNetworkGroup.js.map +1 -1
  23. package/dist/network/networkGroup.js +1 -1
  24. package/dist/network/networkGroup.js.map +1 -1
  25. package/dist/track/trackGroup.js +9 -9
  26. package/dist/track/trackGroup.js.map +1 -1
  27. package/package.json +1 -1
  28. package/src/MX10.ts +13 -13
  29. package/src/data/dataGroup.ts +114 -21
  30. package/src/data/dataMsg.ts +59 -60
  31. package/src/data/lanDataGroup.ts +69 -33
  32. package/src/data/lanDataMsg.ts +71 -0
  33. package/src/file/fileControlGroup.ts +1 -1
  34. package/src/file/fileTransferGroup.ts +1 -1
  35. package/src/info/infoGroup.ts +7 -8
  36. package/src/loco/vehicleGroup.ts +25 -25
  37. package/src/misc/propertyConfigGroup.ts +1 -1
  38. package/src/misc/railwayControlGroup.ts +1 -1
  39. package/src/network/lanNetworkGroup.ts +6 -6
  40. package/src/network/networkGroup.ts +6 -7
  41. package/src/script/lanScriptGroup.ts +1 -1
  42. package/src/script/scriptGroup.ts +1 -1
  43. 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 errors = new Subject<string>();
62
- readonly log = new Subject<string>();
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
- // eslint-disable-next-line no-console
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.log.next("mx10.sendMsg: " + JSON.stringify(buffer));
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.log.next("mx10.sendData: " + JSON.stringify(buffer));
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.errors.next('mx10.connection.not_connected');
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.log.next(err.message);
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.log.next('rx: ' + JSON.stringify(message));
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.log.next('Not from MX10: ' + JSON.stringify(message));
258
+ this.logInfo.next('Not from MX10: ' + JSON.stringify(message));
259
259
  }
260
260
  // else
261
- // this.log.next('This packet is not from our MX10: ' + JSON.stringify(message));
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.log.next(JSON.stringify(message));
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.log.next(msg);
341
+ this.logInfo.next(msg);
342
342
  }
343
343
  }
344
344
  }
@@ -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<ItemListByIndexData>();
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.log.next("mx10.groupCount: failed to acquire lock");
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.log.next(msg);
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.log.next('groupCount query tx: ' + JSON.stringify(msg));
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.log.next('groupCount query rx: ' + JSON.stringify(msg));
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.log.next("mx10.groupCount.rv: " + JSON.stringify(rv));
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(groupNID: number, index: number)
63
+ async listItemsByIndex(groupNid: number, index: number): Promise<MsgItemsByIndexRsp | undefined>
63
64
  {
64
- this.mx10.sendData(0x07, 0x01, [
65
- {value: this.mx10.mx10NID, length: 2},
66
- {value: groupNID, length: 2},
67
- {value: index, length: 2},
68
- ], 0b00);
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.log.next('parseGroupCount: ' + JSON.stringify(buffer));
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.log.next('parseItemListByIndex: ' + JSON.stringify(buffer));
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.log.next('parseItemListByNid: ' + JSON.stringify(buffer));
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.log.next('command not parsed: ' + command.toString());
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
- this.onListItemsByIndex.next({index, nid: deviceNID, msSinceLastCommunication});
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.log.next('parseItemFxMode: ' + JSON.stringify(msg));
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.log.next('parseItemFxConfig: ' + JSON.stringify(msg));
371
+ this.mx10.logInfo.next('parseItemFxConfig: ' + JSON.stringify(msg));
279
372
  this.onItemFxConfig.next(msg);
280
373
  }
281
374
 
@@ -5,87 +5,86 @@ import { MsgMode } from "../common/enums";
5
5
 
6
6
  export class MsgGroupCount extends Message
7
7
  {
8
- public static header(mode: MsgMode, nid: number): Header
9
- {return {group: 0x7, cmd: 0x0, mode: mode, nid: nid}}
8
+ public static header(mode: MsgMode, nid: number): Header
9
+ {return {group: 0x7, cmd: 0x0, mode: mode, nid: nid}}
10
10
 
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
- }
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
- 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;}
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
- public static header(mode: MsgMode, nid: number): Header
29
- {return {group: 0x7, cmd: 0x1, mode: mode, nid: nid}}
28
+ public static header(mode: MsgMode, nid: number): Header
29
+ {return {group: 0x7, cmd: 0x1, mode: mode, nid: nid}}
30
30
 
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
- }
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
- public static header(mode: MsgMode, nid: number): Header
43
- {return {group: 0x7, cmd: 0x1, mode: mode, nid: nid}}
42
+ public static header(mode: MsgMode, nid: number): Header
43
+ {return {group: 0x7, cmd: 0x1, mode: mode, nid: nid}}
44
44
 
45
- constructor(header: Header, index: number, itemNid: number, itemState: number, lastTick: number | undefined)
46
- {
47
- super(header);
48
- super.push({value: index, length: 2});
49
- super.push({value: itemNid, length: 2});
50
- super.push({value: itemState, length: 2});
51
- if(lastTick !== undefined)
52
- super.push({value: lastTick, length: 2});
53
- }
54
- index(): number {return (this.data[1].value as number)}
55
- itemNid(): number {return (this.data[2].value as number)}
56
- itemState(): number {return (this.data[3].value as number)}
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
- public static header(mode: MsgMode, nid: number): Header
63
- {return {group: 0x7, cmd: 0x2, mode: mode, nid: nid}}
61
+ public static header(mode: MsgMode, nid: number): Header
62
+ {return {group: 0x7, cmd: 0x2, mode: mode, nid: nid}}
64
63
 
65
- constructor(header: Header, mx10Nid: number, precedingNid: number)
66
- {
67
- super(header);
68
- super.push({value: mx10Nid, length: 2});
69
- super.push({value: precedingNid, length: 2});
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
- public static header(mode: MsgMode, nid: number): Header
76
- {return {group: 0x7, cmd: 0x2, mode: mode, nid: nid}}
74
+ public static header(mode: MsgMode, nid: number): Header
75
+ {return {group: 0x7, cmd: 0x2, mode: mode, nid: nid}}
77
76
 
78
- constructor(header: Header, itemNid: number, index: number, itemState: number, lastTick: number | undefined)
79
- {
80
- super(header);
81
- super.push({value: itemNid, length: 2});
82
- super.push({value: index, length: 2});
83
- super.push({value: itemState, length: 2});
84
- if(lastTick !== undefined)
85
- super.push({value: lastTick, length: 2});
86
- }
87
- itemNid(): number {return (this.data[1].value as number)}
88
- index(): number {return (this.data[2].value as number)}
89
- itemState(): number {return (this.data[3].value as number)}
90
- lastTick(): number {return (this.data[4].value as number)}
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
  }
@@ -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<Train>();
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(NID: number)
85
+ async locoGuiExtended(nid: number): Promise<MsgLocoGuiRsp | undefined>
83
86
  {
84
- this.mx10.sendData(0x17, 0x27, [
85
- {value: this.mx10.mx10NID, length: 2},
86
- {value: NID, length: 2},
87
- {value: 0, length: 2},
88
- ], 0b00);
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 icon = buffer.readUInt16LE(54 + i * 2);
209
- const iconString =
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
- this.onLocoGuiExtended.next({nid: NID, subId: SubID, name: name, group: vehicleGroup,
218
- image: imageId == 0 ? undefined : imageId.toString(), tacho: tacho.toString(),
219
- speedFwd: speedFwd, speedRev: speedRev, speedRange: speedRange,
220
- operatingMode: OperatingMode.UNKNOWN, driveType: driveType, era: this.parseEra(era),
221
- countryCode: countryCode, functions,
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 < 32; i++) {
290
+ for (let i = 0; i < 64; i++) {
252
291
  const icon = buffer.readUInt16LE(68 + i * 2);
253
- const iconString =
254
- icon === 0 ? String(i).padStart(2, '0') : String(icon);
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