@zimo-elektronik/zcan 1.0.45 → 1.0.47
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/dist/MX10.js +67 -58
- package/dist/MX10.js.map +1 -1
- package/dist/accessory/accessoryCommandGroup.js +1 -1
- package/dist/accessory/accessoryCommandGroup.js.map +1 -1
- package/dist/data/dataGroup.js +1 -9
- package/dist/data/dataGroup.js.map +1 -1
- package/dist/data/lanDataGroup.d.ts +3 -7
- package/dist/data/lanDataGroup.js +48 -49
- package/dist/data/lanDataGroup.js.map +1 -1
- package/dist/data/lanDataMsg.d.ts +2 -2
- package/dist/data/lanDataMsg.js +27 -17
- package/dist/data/lanDataMsg.js.map +1 -1
- package/dist/info/infoGroup.js +1 -1
- package/dist/info/infoGroup.js.map +1 -1
- package/dist/loco/vehicleGroup.d.ts +13 -8
- package/dist/loco/vehicleGroup.js +66 -27
- package/dist/loco/vehicleGroup.js.map +1 -1
- package/dist/loco/vehicleMsg.d.ts +30 -0
- package/dist/loco/vehicleMsg.js +48 -0
- package/dist/loco/vehicleMsg.js.map +1 -1
- package/dist/network/lanNetworkGroup.js +1 -1
- package/dist/network/lanNetworkGroup.js.map +1 -1
- package/package.json +1 -1
- package/src/MX10.ts +67 -60
- package/src/accessory/accessoryCommandGroup.ts +1 -2
- package/src/data/dataGroup.ts +9 -9
- package/src/data/lanDataGroup.ts +110 -96
- package/src/data/lanDataMsg.ts +109 -19
- package/src/info/infoGroup.ts +1 -1
- package/src/loco/vehicleGroup.ts +88 -49
- package/src/loco/vehicleMsg.ts +60 -0
- package/src/network/lanNetworkGroup.ts +1 -2
package/src/info/infoGroup.ts
CHANGED
|
@@ -62,7 +62,7 @@ export default class InfoGroup
|
|
|
62
62
|
this.parseModuleInfo(size, mode, nid, buffer);
|
|
63
63
|
break;
|
|
64
64
|
default:
|
|
65
|
-
this.mx10.logInfo.next('command not parsed: ' +
|
|
65
|
+
this.mx10.logInfo.next('infoGroup command ' + command + ' not parsed: ' + JSON.stringify(buffer));
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
package/src/loco/vehicleGroup.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {Direction, Manual, MaxSpeedSteps, MsgMode, OperatingMode, ShuntingFuncti
|
|
|
6
6
|
} from '../common/enums';
|
|
7
7
|
import {combineSpeedAndDirection} from '../common/speedUtils';
|
|
8
8
|
import { Query } from '../common/communication';
|
|
9
|
-
import { MsgVehicleMode, MsgVehicleSpeed } from './vehicleMsg';
|
|
9
|
+
import { MsgVehicleLastCtl, MsgVehicleMode, MsgVehicleSpeed, MsgVehicleState } from './vehicleMsg';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
*
|
|
@@ -14,12 +14,15 @@ import { MsgVehicleMode, MsgVehicleSpeed } from './vehicleMsg';
|
|
|
14
14
|
*/
|
|
15
15
|
export default class VehicleGroup
|
|
16
16
|
{
|
|
17
|
-
public readonly onVehicleState = new Subject<
|
|
17
|
+
public readonly onVehicleState = new Subject<MsgVehicleState>();
|
|
18
|
+
public readonly onVehicleLastCtl = new Subject<MsgVehicleLastCtl>();
|
|
18
19
|
public readonly onVehicleMode = new Subject<MsgVehicleMode>();
|
|
19
20
|
public readonly onVehicleSpeed = new Subject<MsgVehicleSpeed>(); // VehicleSpeedData
|
|
20
21
|
public readonly onCallFunction = new Subject<CallFunctionData>();
|
|
21
22
|
public readonly onCallSpecialFunction = new Subject<CallSpecialFunctionData>();
|
|
22
23
|
|
|
24
|
+
private stateQ: Query<MsgVehicleState> | undefined = undefined;
|
|
25
|
+
private lastCtlQ: Query<MsgVehicleLastCtl> | undefined = undefined;
|
|
23
26
|
private modeQ: Query<MsgVehicleMode> | undefined = undefined;
|
|
24
27
|
private speedQ: Query<MsgVehicleSpeed> | undefined = undefined;
|
|
25
28
|
|
|
@@ -27,7 +30,57 @@ export default class VehicleGroup
|
|
|
27
30
|
|
|
28
31
|
constructor(mx10: MX10) {this.mx10 = mx10}
|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
//0x02.0x00
|
|
34
|
+
async getState(nid: number)
|
|
35
|
+
{
|
|
36
|
+
if(this.stateQ !== undefined && !await this.stateQ.lock()) {
|
|
37
|
+
this.mx10.logInfo.next("mx10.getVehicleState: failed to acquire lock");
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
this.stateQ = new Query(MsgVehicleState.header(MsgMode.REQ, nid), this.onVehicleState);
|
|
41
|
+
this.stateQ.log = (msg) => {this.mx10.logInfo.next(msg)};
|
|
42
|
+
this.stateQ.tx = ((header) => {
|
|
43
|
+
const msg = new MsgVehicleState(header);
|
|
44
|
+
// this.mx10.logInfo.next('state query tx: ' + JSON.stringify(msg));
|
|
45
|
+
this.mx10.sendMsg(msg);
|
|
46
|
+
});
|
|
47
|
+
this.stateQ.match = ((msg) => {
|
|
48
|
+
// this.mx10.logInfo.next('state query rx: ' + JSON.stringify(msg));
|
|
49
|
+
return (msg.trainNid() === nid);
|
|
50
|
+
})
|
|
51
|
+
const rv = await this.stateQ.run();
|
|
52
|
+
// this.mx10.logInfo.next("mx10.getVehicleState.rv: " + JSON.stringify(rv));
|
|
53
|
+
this.stateQ.unlock();
|
|
54
|
+
this.stateQ = undefined;
|
|
55
|
+
return rv;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//0x02.0x00
|
|
59
|
+
async getLastController(locoNid: number, type: number = 1)
|
|
60
|
+
{
|
|
61
|
+
if(this.lastCtlQ !== undefined && !await this.lastCtlQ.lock()) {
|
|
62
|
+
this.mx10.logInfo.next("mx10.getVehicleLastCtl: failed to acquire lock");
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
this.lastCtlQ = new Query(MsgVehicleLastCtl.header(MsgMode.REQ, locoNid), this.onVehicleLastCtl);
|
|
66
|
+
this.lastCtlQ.log = (msg) => {this.mx10.logInfo.next(msg)};
|
|
67
|
+
this.lastCtlQ.tx = ((header) => {
|
|
68
|
+
const msg = new MsgVehicleLastCtl(header, type);
|
|
69
|
+
this.mx10.logInfo.next('lastCtl query tx: ' + JSON.stringify(msg));
|
|
70
|
+
this.mx10.sendMsg(msg);
|
|
71
|
+
});
|
|
72
|
+
this.lastCtlQ.match = ((msg) => {
|
|
73
|
+
this.mx10.logInfo.next('lastCtl query rx: ' + JSON.stringify(msg));
|
|
74
|
+
return (msg.trainNid() === locoNid);
|
|
75
|
+
})
|
|
76
|
+
const rv = await this.lastCtlQ.run();
|
|
77
|
+
this.mx10.logInfo.next("mx10.getVehicleLastCtl.rv: " + JSON.stringify(rv));
|
|
78
|
+
this.lastCtlQ.unlock();
|
|
79
|
+
this.lastCtlQ = undefined;
|
|
80
|
+
return rv;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async getMode(trainNid: number)
|
|
31
84
|
{
|
|
32
85
|
if(this.modeQ !== undefined && !await this.modeQ.lock()) {
|
|
33
86
|
this.mx10.logInfo.next("mx10.getVehicleMode: failed to acquire lock");
|
|
@@ -45,13 +98,13 @@ export default class VehicleGroup
|
|
|
45
98
|
return (msg.trainNid() === trainNid);
|
|
46
99
|
})
|
|
47
100
|
const rv = await this.modeQ.run();
|
|
48
|
-
this.mx10.logInfo.next("mx10.getVehicleMode.rv: " + JSON.stringify(rv));
|
|
101
|
+
// this.mx10.logInfo.next("mx10.getVehicleMode.rv: " + JSON.stringify(rv));
|
|
49
102
|
this.modeQ.unlock();
|
|
50
103
|
this.modeQ = undefined;
|
|
51
104
|
return rv;
|
|
52
105
|
}
|
|
53
106
|
|
|
54
|
-
async
|
|
107
|
+
async setMode(trainNid: number, opMode: OperatingMode, speedSteps: MaxSpeedSteps)
|
|
55
108
|
{
|
|
56
109
|
MsgVehicleMode.log = (msg) => {this.mx10.logInfo.next(msg)};
|
|
57
110
|
if(this.modeQ !== undefined && !await this.modeQ.lock()) {
|
|
@@ -62,21 +115,21 @@ export default class VehicleGroup
|
|
|
62
115
|
this.modeQ.log = (msg) => {this.mx10.logInfo.next(msg)};
|
|
63
116
|
this.modeQ.tx = ((header) => {
|
|
64
117
|
const msg = new MsgVehicleMode(header, {opMode, speedSteps});
|
|
65
|
-
this.mx10.logInfo.next('mode query tx: ' + JSON.stringify(msg));
|
|
118
|
+
// this.mx10.logInfo.next('mode query tx: ' + JSON.stringify(msg));
|
|
66
119
|
this.mx10.sendMsg(msg);
|
|
67
120
|
});
|
|
68
121
|
this.modeQ.match = ((msg) => {
|
|
69
|
-
this.mx10.logInfo.next('mode query rx: ' + JSON.stringify(msg));
|
|
122
|
+
// this.mx10.logInfo.next('mode query rx: ' + JSON.stringify(msg));
|
|
70
123
|
return (msg.trainNid() === trainNid);
|
|
71
124
|
})
|
|
72
125
|
const rv = await this.modeQ.run(MsgVehicleMode.rxDelay());
|
|
73
|
-
this.mx10.logInfo.next("mx10.setVehicleMode.rv: " + JSON.stringify(rv));
|
|
126
|
+
// this.mx10.logInfo.next("mx10.setVehicleMode.rv: " + JSON.stringify(rv));
|
|
74
127
|
this.modeQ.unlock();
|
|
75
128
|
this.modeQ = undefined;
|
|
76
129
|
return rv;
|
|
77
130
|
}
|
|
78
131
|
|
|
79
|
-
async
|
|
132
|
+
async getSpeed(trainNid: number)
|
|
80
133
|
{
|
|
81
134
|
if(this.speedQ !== undefined && !await this.speedQ.lock()) {
|
|
82
135
|
this.mx10.logInfo.next("mx10.getVehicleSpeed: failed to acquire lock");
|
|
@@ -94,13 +147,13 @@ export default class VehicleGroup
|
|
|
94
147
|
return (msg.trainNid() === trainNid);
|
|
95
148
|
})
|
|
96
149
|
const rv = await this.speedQ.run();
|
|
97
|
-
this.mx10.logInfo.next("mx10.getVehicleSpeed.rv: " + JSON.stringify(rv));
|
|
150
|
+
// this.mx10.logInfo.next("mx10.getVehicleSpeed.rv: " + JSON.stringify(rv));
|
|
98
151
|
this.speedQ.unlock();
|
|
99
152
|
this.speedQ = undefined;
|
|
100
153
|
return rv;
|
|
101
154
|
}
|
|
102
155
|
|
|
103
|
-
async
|
|
156
|
+
async setSpeed(trainNid: number, speedStep: number, divisor: number = 0, forward: boolean = true,
|
|
104
157
|
emergencyStop: boolean = false, eastWest: Direction = Direction.UNDEFINED)
|
|
105
158
|
{
|
|
106
159
|
MsgVehicleSpeed.log = (msg) => {this.mx10.logInfo.next(msg)};
|
|
@@ -113,15 +166,15 @@ export default class VehicleGroup
|
|
|
113
166
|
this.speedQ.tx = ((header) => {
|
|
114
167
|
const speedAndDir= MsgVehicleSpeed.speedAndDir(speedStep, forward, emergencyStop, eastWest);
|
|
115
168
|
const msg = new MsgVehicleSpeed(header, speedAndDir, divisor);
|
|
116
|
-
this.mx10.logInfo.next('speed query tx: ' + JSON.stringify(msg));
|
|
169
|
+
// this.mx10.logInfo.next('speed query tx: ' + JSON.stringify(msg));
|
|
117
170
|
this.mx10.sendMsg(msg);
|
|
118
171
|
});
|
|
119
172
|
this.speedQ.match = ((msg) => {
|
|
120
|
-
this.mx10.logInfo.next('speed query rx: ' + JSON.stringify(msg));
|
|
173
|
+
// this.mx10.logInfo.next('speed query rx: ' + JSON.stringify(msg));
|
|
121
174
|
return (msg.trainNid() === trainNid);
|
|
122
175
|
})
|
|
123
176
|
const rv = await this.speedQ.run(MsgVehicleSpeed.rxDelay());
|
|
124
|
-
this.mx10.logInfo.next("mx10.setVehicleSpeed.rv: " + JSON.stringify(rv));
|
|
177
|
+
// this.mx10.logInfo.next("mx10.setVehicleSpeed.rv: " + JSON.stringify(rv));
|
|
125
178
|
this.speedQ.unlock();
|
|
126
179
|
this.speedQ = undefined;
|
|
127
180
|
return rv;
|
|
@@ -155,11 +208,6 @@ export default class VehicleGroup
|
|
|
155
208
|
]);
|
|
156
209
|
}
|
|
157
210
|
|
|
158
|
-
//0x02.0x00
|
|
159
|
-
vehicleState(vehicleAddress: number) {
|
|
160
|
-
return this.mx10.sendData(0x02, 0x00, [{value: vehicleAddress, length: 2}], 0b00);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
211
|
// 0x02.0x10
|
|
164
212
|
activeModeTrain(vehicleAddress: number) {
|
|
165
213
|
return this.mx10.sendData(0x02, 0x10, [
|
|
@@ -184,24 +232,18 @@ export default class VehicleGroup
|
|
|
184
232
|
case 0x02: this.parseVehicleSpeed(size, mode, nid, buffer); break;
|
|
185
233
|
case 0x04: this.parseVehicleFunction(size, mode, nid, buffer); break;
|
|
186
234
|
case 0x05: this.parseVehicleSpecialFunction(size, mode, nid, buffer); break;
|
|
235
|
+
case 0x12: this.parseVehicleLastCtl(size, mode, nid, buffer); break;
|
|
187
236
|
}
|
|
188
237
|
}
|
|
189
238
|
|
|
190
239
|
// 0x02.0x00
|
|
191
240
|
private parseVehicleState( size: number, mode: number, nid: number, buffer: Buffer)
|
|
192
241
|
{
|
|
193
|
-
if
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
this.onVehicleState.next({
|
|
200
|
-
nid: NID,
|
|
201
|
-
ctrlTick,
|
|
202
|
-
ctrlDevice,
|
|
203
|
-
});
|
|
204
|
-
}
|
|
242
|
+
if(!this.onVehicleState.observed)
|
|
243
|
+
return;
|
|
244
|
+
const msg = MsgVehicleState.fromBuffer(mode, buffer);
|
|
245
|
+
// this.mx10.logInfo.next('parseVehicleState' + JSON.stringify(buffer));
|
|
246
|
+
this.onVehicleState.next(msg);
|
|
205
247
|
}
|
|
206
248
|
|
|
207
249
|
// 0x02.0x01
|
|
@@ -224,23 +266,6 @@ export default class VehicleGroup
|
|
|
224
266
|
const msg = MsgVehicleSpeed.fromBuffer(mode, buffer);
|
|
225
267
|
// this.mx10.logInfo.next('parseVehicleSpeed: ' + JSON.stringify(msg));
|
|
226
268
|
this.onVehicleSpeed.next(msg);
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
// const NID = buffer.readUInt16LE(0);
|
|
230
|
-
// const speedAndDirection = buffer.readUInt16LE(2);
|
|
231
|
-
// const divisor = buffer.readUint8(4);
|
|
232
|
-
|
|
233
|
-
// const {speedStep, forward, eastWest, emergencyStop} =
|
|
234
|
-
// parseSpeed(speedAndDirection);
|
|
235
|
-
|
|
236
|
-
// {
|
|
237
|
-
// nid: NID,
|
|
238
|
-
// divisor,
|
|
239
|
-
// speedStep,
|
|
240
|
-
// forward,
|
|
241
|
-
// eastWest,
|
|
242
|
-
// emergencyStop,
|
|
243
|
-
// });
|
|
244
269
|
}
|
|
245
270
|
|
|
246
271
|
// 0x02.0x04
|
|
@@ -250,7 +275,6 @@ export default class VehicleGroup
|
|
|
250
275
|
const NID = buffer.readUInt16LE(0);
|
|
251
276
|
const functionNumber = buffer.readUInt16LE(2);
|
|
252
277
|
const functionState = buffer.readUInt16LE(4);
|
|
253
|
-
|
|
254
278
|
const functionActive = functionState !== 0x00;
|
|
255
279
|
|
|
256
280
|
this.onCallFunction.next({
|
|
@@ -276,4 +300,19 @@ export default class VehicleGroup
|
|
|
276
300
|
});
|
|
277
301
|
}
|
|
278
302
|
}
|
|
303
|
+
|
|
304
|
+
// 0x02.0x12
|
|
305
|
+
private parseVehicleLastCtl( size: number, mode: number, nid: number, buffer: Buffer)
|
|
306
|
+
{
|
|
307
|
+
if(!this.onVehicleLastCtl.observed)
|
|
308
|
+
return;
|
|
309
|
+
|
|
310
|
+
const NID = buffer.readUInt16LE(0);
|
|
311
|
+
const type = buffer.readUInt16LE(2);
|
|
312
|
+
const ctlNid = buffer.readUInt16LE(4);
|
|
313
|
+
const seconds = buffer.readUInt16LE(6);
|
|
314
|
+
|
|
315
|
+
const msg = new MsgVehicleLastCtl(MsgVehicleLastCtl.header(mode, NID), type, ctlNid, seconds);
|
|
316
|
+
this.onVehicleLastCtl.next(msg);
|
|
317
|
+
}
|
|
279
318
|
}
|
package/src/loco/vehicleMsg.ts
CHANGED
|
@@ -102,4 +102,64 @@ export class MsgVehicleSpeed extends Message
|
|
|
102
102
|
const stop = Number(emergencyStop);
|
|
103
103
|
return speed | (direction << 10) | (eastWest << 12) | (stop << 15);
|
|
104
104
|
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export class MsgVehicleState extends Message
|
|
108
|
+
{
|
|
109
|
+
public static header = (mode: MsgMode, nid: number) => {return {group: 0x2, cmd: 0x0, mode, nid}}
|
|
110
|
+
public static log: (msg: string) => void = () => {};
|
|
111
|
+
|
|
112
|
+
constructor(header: Header, flags?: number, lastTick?: number, lastNid?: number)
|
|
113
|
+
{
|
|
114
|
+
super(header);
|
|
115
|
+
if(header.mode === MsgMode.REQ)
|
|
116
|
+
return;
|
|
117
|
+
super.push({value: flags || 0, length: 2});
|
|
118
|
+
super.push({value: lastTick || 0, length: 2});
|
|
119
|
+
super.push({value: lastNid || 0, length: 2});
|
|
120
|
+
}
|
|
121
|
+
trainNid(): number {return this.header.nid || 0}
|
|
122
|
+
stateFlags(): number {return this.data[0].value as number;}
|
|
123
|
+
lastCtlTick(): number {return this.data[1].value as number;}
|
|
124
|
+
lastCtlNid(): number {return this.data[2].value as number;}
|
|
125
|
+
|
|
126
|
+
public static fromBuffer(mode: MsgMode, buffer: Buffer)
|
|
127
|
+
{
|
|
128
|
+
const nid = buffer.readUInt16LE(0);
|
|
129
|
+
const flags = buffer.readUInt16LE(2);
|
|
130
|
+
const lastTick = buffer.readUint16LE(4);
|
|
131
|
+
const lastNid = buffer.readUint16LE(6);
|
|
132
|
+
const msg = new MsgVehicleState(MsgVehicleState.header(mode, nid), flags, lastTick, lastNid);
|
|
133
|
+
return msg;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export class MsgVehicleLastCtl extends Message
|
|
138
|
+
{
|
|
139
|
+
public static header = (mode: MsgMode, nid: number) => {return {group: 0x2, cmd: 0x12, mode, nid}}
|
|
140
|
+
public static log: (msg: string) => void = () => {};
|
|
141
|
+
|
|
142
|
+
constructor(header: Header, type: number, lastNid?: number, lastTick?: number)
|
|
143
|
+
{
|
|
144
|
+
super(header);
|
|
145
|
+
super.push({value: type, length: 2});
|
|
146
|
+
if(header.mode === MsgMode.REQ)
|
|
147
|
+
return;
|
|
148
|
+
super.push({value: lastNid || 0, length: 2});
|
|
149
|
+
super.push({value: lastTick || 0, length: 2});
|
|
150
|
+
}
|
|
151
|
+
trainNid(): number {return this.header.nid || 0}
|
|
152
|
+
type(): number {return this.data[0].value as number;}
|
|
153
|
+
ctlNid(): number {return this.data[1].value as number;}
|
|
154
|
+
seconds(): number {return this.data[2].value as number;}
|
|
155
|
+
|
|
156
|
+
public static fromBuffer(mode: MsgMode, buffer: Buffer)
|
|
157
|
+
{
|
|
158
|
+
const nid = buffer.readUInt16LE(0);
|
|
159
|
+
const type = buffer.readUInt16LE(2);
|
|
160
|
+
const ctlNid = buffer.readUint16LE(4);
|
|
161
|
+
const seconds = buffer.readUint16LE(6);
|
|
162
|
+
const msg = new MsgVehicleLastCtl(MsgVehicleLastCtl.header(mode, nid), type, ctlNid, seconds);
|
|
163
|
+
return msg;
|
|
164
|
+
}
|
|
105
165
|
}
|
|
@@ -77,8 +77,7 @@ export default class LanNetworkGroup
|
|
|
77
77
|
this.parseUnknownCommand(size, mode, nid, buffer);
|
|
78
78
|
break;
|
|
79
79
|
default:
|
|
80
|
-
|
|
81
|
-
console.warn('command not parsed: ' + command.toString());
|
|
80
|
+
this.mx10.logInfo.next('lanNetworkGroup command ' + command + ' not parsed: ' + JSON.stringify(buffer));
|
|
82
81
|
}
|
|
83
82
|
}
|
|
84
83
|
|