@tsplc/debug 0.2.16 → 0.2.18

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/src/ui/fixture.ts DELETED
@@ -1,548 +0,0 @@
1
- import type { Quality } from "../api.ts";
2
- import type { DebugEventSite, DebugManifest, DebugType, SourceRange } from "../manifest.ts";
3
-
4
- /** A conveyor line's debug manifest for `dev.ts`: diverters, scanners, an inbound conveyor and ~5000 paths. */
5
-
6
- const at = (file: number, line: number, column = 5, length = 24): SourceRange => ({
7
- file,
8
- line,
9
- column,
10
- endLine: line,
11
- endColumn: column + length,
12
- });
13
-
14
- const record = (
15
- name: string,
16
- file: number,
17
- fields: [string, string, number, true?][],
18
- ): DebugType => ({
19
- kind: "record",
20
- name,
21
- declaration: at(file, Math.min(...fields.map(([, , line]) => line)) - 1, 1),
22
- fields: fields.map(([field, type, line, generated]) => ({
23
- name: field,
24
- target: field,
25
- type,
26
- declaration: at(file, line),
27
- ...(generated ? { generated } : {}),
28
- })),
29
- });
30
-
31
- const array = (element: string, length: number): DebugType => ({
32
- kind: "array",
33
- element,
34
- length,
35
- lower: 0,
36
- });
37
-
38
- const binSites: DebugEventSite[] = Array.from({ length: 16 }, (_, index) => [
39
- {
40
- id: 100 + index,
41
- kind: "state" as const,
42
- path: `program.diverters.binTrackers[${index}].bin`,
43
- function: 1,
44
- type: "Bin",
45
- range: at(1, 41, 7, 24),
46
- text: "this.bin = Bin.Present;",
47
- task: "MainTask",
48
- operands: [
49
- {
50
- text: "exit",
51
- range: at(1, 39, 11, 4),
52
- type: "BOOL",
53
- path: `line.conveyors.inbound.cards[${index % 10}].input.sensor`,
54
- stable: true,
55
- },
56
- {
57
- text: "this.count",
58
- range: at(1, 39, 19, 10),
59
- type: "DINT",
60
- path: `program.diverters.binTrackers[${index}].count`,
61
- stable: false,
62
- },
63
- ],
64
- },
65
- {
66
- id: 200 + index,
67
- kind: "state" as const,
68
- path: `program.diverters.binTrackers[${index}].bin`,
69
- function: 1,
70
- type: "Bin",
71
- range: at(1, 33, 7, 25),
72
- text: "this.bin = Bin.Arriving;",
73
- task: "MainTask",
74
- operands: [
75
- { text: "entry", range: at(1, 31, 11, 5), type: "BOOL", stable: true },
76
- { text: "this.bin === Bin.None", range: at(1, 31, 20, 21), type: "BOOL", stable: true },
77
- ],
78
- },
79
- ]).flat();
80
-
81
- const routeSites: DebugEventSite[] = Array.from({ length: 4 }, (_, index) => ({
82
- id: 300 + index,
83
- kind: "decision",
84
- path: `program.scanners.routeLookups[${index}].lane`,
85
- function: 2,
86
- type: "INT",
87
- range: at(2, 31, 7, 18),
88
- text: "return route.lane;",
89
- task: "ServiceTask",
90
- operands: [{ text: "route.ok", range: at(2, 29, 9, 8), type: "BOOL", stable: true }],
91
- }));
92
-
93
- const resolveSteps = [
94
- { step: 0, kind: "statement" as const, range: at(2, 22), text: "this.pending = true;" },
95
- {
96
- step: 1,
97
- kind: "await" as const,
98
- range: at(2, 24, 18, 46),
99
- text: "await services.routing.resolve({ code: this.code })",
100
- },
101
- { step: 2, kind: "statement" as const, range: at(2, 27), text: "this.lane = route.lane;" },
102
- { step: 3, kind: "return" as const, range: at(2, 31), text: "return route.lane;" },
103
- ];
104
-
105
- export const fixtureManifest: DebugManifest = {
106
- kind: "tsplc-debug",
107
- version: 1,
108
- build: { id: "c41f7e2a9b0d", target: "GVL_TsplcDebug.build", compiler: "0.2.13" },
109
- sources: [
110
- "src/program.ts",
111
- "src/diverters/bin-tracker.ts",
112
- "src/scanners/route-lookup.ts",
113
- "src/line/inbound.ts",
114
- "src/tracking.ts",
115
- "src/settings.ts",
116
- ],
117
- types: {
118
- BOOL: { kind: "scalar", iec: "BOOL" },
119
- INT: { kind: "scalar", iec: "INT" },
120
- DINT: { kind: "scalar", iec: "DINT" },
121
- REAL: { kind: "scalar", iec: "REAL" },
122
- STRING: { kind: "scalar", iec: "STRING" },
123
- Bin: { kind: "enum", name: "Bin", members: { None: 0, Arriving: 1, Present: 2 } },
124
- Mode: { kind: "enum", name: "Mode", members: { Stopped: 0, Running: 1, Faulted: 2 } },
125
- ParcelState: {
126
- kind: "enum",
127
- name: "ParcelState",
128
- members: { Inducted: 0, Scanned: 1, Routed: 2, Diverted: 3, Lost: 4 },
129
- },
130
- BinTracker: record("BinTracker", 1, [
131
- ["bin", "Bin", 8],
132
- ["count", "DINT", 9],
133
- ["exitClear", "BOOL", 10],
134
- ["lastCode", "STRING", 11],
135
- ["releaseStep", "DINT", 12, true],
136
- ]),
137
- "BinTracker[16]": array("BinTracker", 16),
138
- RouteLookup: record("RouteLookup", 2, [
139
- ["code", "STRING", 8],
140
- ["lane", "INT", 9],
141
- ["pending", "BOOL", 10],
142
- ["attempts", "INT", 11],
143
- ["step", "DINT", 12, true],
144
- ["busy", "BOOL", 13, true],
145
- ]),
146
- "RouteLookup[4]": array("RouteLookup", 4),
147
- CardInput: record("CardInput", 3, [
148
- ["sensor", "BOOL", 6],
149
- ["jam", "BOOL", 7],
150
- ]),
151
- CardOutput: record("CardOutput", 3, [
152
- ["motor", "BOOL", 11],
153
- ["speed", "REAL", 12],
154
- ]),
155
- Card: record("Card", 3, [
156
- ["input", "CardInput", 16],
157
- ["output", "CardOutput", 17],
158
- ]),
159
- "Card[10]": array("Card", 10),
160
- Parcel: record("Parcel", 4, [
161
- ["code", "STRING", 5],
162
- ["lane", "INT", 6],
163
- ["zone", "INT", 7],
164
- ["state", "ParcelState", 8],
165
- ["weightKg", "REAL", 9],
166
- ["diverted", "BOOL", 10],
167
- ]),
168
- "Parcel[768]": array("Parcel", 768),
169
- Settings: record("Settings", 5, [
170
- ["speed", "REAL", 4],
171
- ["accumulation", "BOOL", 5],
172
- ]),
173
- Scratch: record("Scratch", 0, [["buffer", "DINT", 40]]),
174
- },
175
- roots: [
176
- {
177
- path: "program.mode",
178
- target: "plc_Program.mode",
179
- type: "Mode",
180
- declaration: at(0, 12),
181
- readable: true,
182
- },
183
- {
184
- path: "program.diverters.binTrackers",
185
- target: "plc_Program.diverters.binTrackers",
186
- type: "BinTracker[16]",
187
- declaration: at(0, 14),
188
- readable: true,
189
- },
190
- {
191
- path: "program.scanners.routeLookups",
192
- target: "plc_Program.scanners.routeLookups",
193
- type: "RouteLookup[4]",
194
- declaration: at(0, 17),
195
- readable: true,
196
- },
197
- {
198
- path: "line.conveyors.inbound.cards",
199
- target: "GVL_Line.inbound_cards",
200
- type: "Card[10]",
201
- declaration: at(3, 22),
202
- readable: true,
203
- },
204
- {
205
- path: "program.tracking.parcels",
206
- target: "plc_Program.tracking.parcels",
207
- type: "Parcel[768]",
208
- declaration: at(4, 14),
209
- readable: true,
210
- },
211
- {
212
- path: "program.settings",
213
- target: "plc_Program.settings",
214
- type: "Settings",
215
- declaration: at(0, 20),
216
- readable: true,
217
- },
218
- {
219
- path: "program.diagnostics.scratch",
220
- target: "plc_Program.diagnostics.scratch",
221
- type: "Scratch",
222
- declaration: at(0, 38),
223
- readable: false,
224
- },
225
- ],
226
- constants: [
227
- { path: "program.settings.lanes", type: "INT", value: 4, declaration: at(5, 6) },
228
- {
229
- path: "program.settings.lineName",
230
- type: "STRING",
231
- value: "Inbound A",
232
- declaration: at(5, 7),
233
- },
234
- { path: "program.diverters.maxBins", type: "DINT", value: 16, declaration: at(1, 3) },
235
- { path: "program.scanners.timeoutMs", type: "DINT", value: 1500, declaration: at(2, 3) },
236
- ],
237
- io: [
238
- ...Array.from({ length: 10 }, (_, index) => ({
239
- path: `line.conveyors.inbound.cards[${index}].input.sensor`,
240
- target: `GVL_Io.inbound_di${index}`,
241
- direction: "input" as const,
242
- type: "BOOL",
243
- device: "io-inbound-1",
244
- channel: `di${index}`,
245
- address: `%IX${index >> 3}.${index & 7}`,
246
- })),
247
- ...Array.from({ length: 10 }, (_, index) => ({
248
- path: `line.conveyors.inbound.cards[${index}].output.motor`,
249
- target: `GVL_Io.inbound_do${index}`,
250
- direction: "output" as const,
251
- type: "BOOL",
252
- device: "io-inbound-1",
253
- channel: `do${index}`,
254
- address: `%QX${index >> 3}.${index & 7}`,
255
- })),
256
- {
257
- path: "line.conveyors.inbound.cards[0].input.jam",
258
- target: "GVL_Io.inbound_jam",
259
- direction: "input",
260
- type: "BOOL",
261
- device: "io-inbound-1",
262
- channel: "di12",
263
- address: "%IX1.4",
264
- inverted: true,
265
- },
266
- {
267
- path: "line.conveyors.inbound.cards[0].output.speed",
268
- target: "GVL_Io.vfd_setpoint",
269
- direction: "output",
270
- type: "REAL",
271
- device: "vfd-inbound",
272
- channel: "setpoint",
273
- address: "%QW12",
274
- },
275
- ],
276
- devices: [
277
- {
278
- id: "io-inbound-1",
279
- vendor: "Turck",
280
- product: "FEN20-16DXP",
281
- productCode: "6814023",
282
- network: { address: "192.168.10.21", rpiMs: 10 },
283
- connection: "Exclusive owner",
284
- assemblies: [
285
- { direction: "input", bytes: 4, address: "%IB0", raw: "GVL_TsplcDebug.io_inbound_1_in" },
286
- { direction: "output", bytes: 2, address: "%QB0", raw: "GVL_TsplcDebug.io_inbound_1_out" },
287
- ],
288
- health: {
289
- state: "GVL_TsplcDebug.io_inbound_1_state",
290
- diagnostic: "GVL_TsplcDebug.io_inbound_1_diag",
291
- },
292
- status: {
293
- "Module power": "GVL_Io.inbound_power_ok",
294
- "Bus fault": "GVL_Io.inbound_bus_fault",
295
- },
296
- channels: [
297
- ...Array.from({ length: 10 }, (_, index) => ({
298
- id: `di${index}`,
299
- name: `Zone ${index + 1} photo eye`,
300
- direction: "input" as const,
301
- type: "BOOL",
302
- offsetBits: index,
303
- bits: 1,
304
- address: `%IX${index >> 3}.${index & 7}`,
305
- })),
306
- {
307
- id: "di12",
308
- name: "Jam switch",
309
- direction: "input",
310
- type: "BOOL",
311
- offsetBits: 12,
312
- bits: 1,
313
- address: "%IX1.4",
314
- description: "Normally closed",
315
- },
316
- {
317
- id: "diag",
318
- name: "Module diagnostics",
319
- direction: "input",
320
- type: "WORD",
321
- offsetBits: 16,
322
- bits: 16,
323
- address: "%IW1",
324
- },
325
- ...Array.from({ length: 10 }, (_, index) => ({
326
- id: `do${index}`,
327
- name: `Zone ${index + 1} motor`,
328
- direction: "output" as const,
329
- type: "BOOL",
330
- offsetBits: index,
331
- bits: 1,
332
- address: `%QX${index >> 3}.${index & 7}`,
333
- })),
334
- ],
335
- },
336
- {
337
- id: "scanner-1",
338
- vendor: "Cognex",
339
- product: "DataMan 370",
340
- productCode: "DMR-370S",
341
- network: { address: "192.168.10.31", rpiMs: 20 },
342
- connection: "Exclusive owner",
343
- assemblies: [
344
- { direction: "input", bytes: 8, address: "%IB20", raw: "GVL_TsplcDebug.scanner_1_in" },
345
- { direction: "output", bytes: 2, address: "%QB20" },
346
- ],
347
- channels: [
348
- {
349
- id: "ready",
350
- name: "Trigger ready",
351
- direction: "input",
352
- type: "BOOL",
353
- offsetBits: 0,
354
- bits: 1,
355
- },
356
- {
357
- id: "ack",
358
- name: "Trigger acknowledge",
359
- direction: "input",
360
- type: "BOOL",
361
- offsetBits: 1,
362
- bits: 1,
363
- },
364
- {
365
- id: "complete",
366
- name: "Read complete",
367
- direction: "input",
368
- type: "BOOL",
369
- offsetBits: 2,
370
- bits: 1,
371
- },
372
- {
373
- id: "resultId",
374
- name: "Result id",
375
- direction: "input",
376
- type: "UINT",
377
- offsetBits: 16,
378
- bits: 16,
379
- },
380
- {
381
- id: "length",
382
- name: "Result length",
383
- direction: "input",
384
- type: "UINT",
385
- offsetBits: 32,
386
- bits: 16,
387
- unit: "bytes",
388
- },
389
- {
390
- id: "trigger",
391
- name: "Trigger",
392
- direction: "output",
393
- type: "BOOL",
394
- offsetBits: 0,
395
- bits: 1,
396
- },
397
- ],
398
- },
399
- {
400
- id: "vfd-inbound",
401
- vendor: "SEW-Eurodrive",
402
- product: "MOVIDRIVE B",
403
- network: { address: "192.168.10.41", rpiMs: 10 },
404
- connection: "Exclusive owner",
405
- assemblies: [
406
- { direction: "input", bytes: 4, address: "%IB40", raw: "GVL_TsplcDebug.vfd_inbound_in" },
407
- { direction: "output", bytes: 4, address: "%QB40", raw: "GVL_TsplcDebug.vfd_inbound_out" },
408
- ],
409
- health: {
410
- state: "GVL_TsplcDebug.vfd_inbound_state",
411
- message: "GVL_TsplcDebug.vfd_inbound_message",
412
- },
413
- channels: [
414
- {
415
- id: "status",
416
- name: "Status word",
417
- direction: "input",
418
- type: "WORD",
419
- offsetBits: 0,
420
- bits: 16,
421
- },
422
- {
423
- id: "actual",
424
- name: "Actual speed",
425
- direction: "input",
426
- type: "INT",
427
- offsetBits: 16,
428
- bits: 16,
429
- unit: "rpm",
430
- },
431
- {
432
- id: "control",
433
- name: "Control word",
434
- direction: "output",
435
- type: "WORD",
436
- offsetBits: 0,
437
- bits: 16,
438
- },
439
- {
440
- id: "setpoint",
441
- name: "Speed setpoint",
442
- direction: "output",
443
- type: "INT",
444
- offsetBits: 16,
445
- bits: 16,
446
- unit: "rpm",
447
- },
448
- ],
449
- },
450
- ],
451
- functions: [
452
- {
453
- id: 1,
454
- name: "BinTracker.update",
455
- declaration: at(1, 28),
456
- task: "MainTask",
457
- target: "BinTracker.update",
458
- reads: [],
459
- },
460
- {
461
- id: 2,
462
- name: "RouteLookup.resolve",
463
- declaration: at(2, 20),
464
- task: "ServiceTask",
465
- target: "RouteLookup.resolve",
466
- reads: [],
467
- },
468
- ],
469
- jobs: [
470
- ...Array.from({ length: 4 }, (_, index) => ({
471
- id: index + 1,
472
- name: "RouteLookup.resolve",
473
- declaration: at(2, 20),
474
- instance: `program.scanners.routeLookups[${index}]`,
475
- target: `plc_Program.scanners.routeLookups[${index}].job`,
476
- steps: resolveSteps,
477
- requests: [{ service: "routing.resolve", target: "x", sequence: "y" }],
478
- })),
479
- {
480
- id: 5,
481
- name: "BinTracker.release",
482
- declaration: at(1, 52),
483
- instance: "program.diverters.binTrackers[3]",
484
- target: "plc_Program.diverters.binTrackers[3].release",
485
- steps: [
486
- {
487
- step: 1,
488
- kind: "await",
489
- range: at(1, 55, 7, 40),
490
- text: "await services.bins.release({ bin: 3 })",
491
- },
492
- ],
493
- requests: [{ service: "bins.release", target: "x", sequence: "y" }],
494
- },
495
- ],
496
- events: [
497
- ...binSites,
498
- ...routeSites,
499
- {
500
- id: 400,
501
- kind: "state",
502
- path: "program.mode",
503
- type: "Mode",
504
- range: at(0, 61, 7, 26),
505
- text: "this.mode = Mode.Faulted;",
506
- task: "MainTask",
507
- operands: [{ text: "drive.fault", range: at(0, 60, 9, 11), type: "BOOL", stable: true }],
508
- },
509
- ],
510
- writers: [],
511
- tasks: [
512
- {
513
- name: "MainTask",
514
- intervalMs: 10,
515
- priority: 1,
516
- },
517
- {
518
- name: "ServiceTask",
519
- intervalMs: 50,
520
- priority: 5,
521
- },
522
- ],
523
- errors: { "1": "Cancelled", "2": "Timeout", "3": "ServiceError" },
524
- };
525
-
526
- const hash = (text: string) =>
527
- [...text].reduce((sum, char) => (sum * 31 + char.charCodeAt(0)) >>> 0, 7) % 997;
528
-
529
- /** A deterministic value for `path` at time `ms`, so samples and raw bytes agree. */
530
- export const fixtureValue = (path: string, type: string, ms: number): unknown => {
531
- const seed = hash(path);
532
- const tick = (period: number) => Math.floor(ms / period + seed);
533
- if (path === "program.mode") return 1;
534
- if (type === "Bin") return tick(3100) % 3;
535
- if (type === "ParcelState") return tick(4300) % 5;
536
- if (type === "BOOL") return tick(700 + (seed % 900)) % 2 === 0;
537
- if (type === "REAL") return Math.round((40 + 10 * Math.sin(ms / 3000 + seed)) * 100) / 100;
538
- if (type === "STRING") return `P${String(tick(5000) % 100000).padStart(5, "0")}`;
539
- if (path.endsWith(".lane")) return tick(4000) % 4;
540
- return tick(2000) % 32767;
541
- };
542
-
543
- export const fixtureQuality = (path: string): { quality: Quality; status: string } => {
544
- if (path.includes("routeLookups[3]")) return { quality: "bad", status: "BadCommunicationError" };
545
- if (path.includes("binTrackers[7]"))
546
- return { quality: "uncertain", status: "UncertainLastUsableValue" };
547
- return { quality: "good", status: "Good" };
548
- };