ultimatedarktower 2.5.0 → 3.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/CHANGELOG.md +19 -1
- package/README.md +65 -65
- package/dist/esm/index.mjs +231 -223
- package/dist/src/UltimateDarkTower.d.ts +6 -6
- package/dist/src/UltimateDarkTower.js +13 -51
- package/dist/src/UltimateDarkTower.js.map +1 -1
- package/dist/src/udtBleConnection.d.ts +4 -4
- package/dist/src/udtBleConnection.js +12 -11
- package/dist/src/udtBleConnection.js.map +1 -1
- package/dist/src/udtBluetoothAdapter.d.ts +2 -2
- package/dist/src/udtCommandFactory.d.ts +6 -0
- package/dist/src/udtCommandFactory.js +26 -22
- package/dist/src/udtCommandFactory.js.map +1 -1
- package/dist/src/udtCommandQueue.d.ts +2 -2
- package/dist/src/udtCommandQueue.js +2 -3
- package/dist/src/udtCommandQueue.js.map +1 -1
- package/dist/src/udtConstants.d.ts +1 -8
- package/dist/src/udtConstants.js.map +1 -1
- package/dist/src/udtLogger.d.ts +1 -0
- package/dist/src/udtLogger.js +24 -2
- package/dist/src/udtLogger.js.map +1 -1
- package/dist/src/udtTowerCommands.d.ts +2 -2
- package/dist/src/udtTowerCommands.js +17 -14
- package/dist/src/udtTowerCommands.js.map +1 -1
- package/dist/src/udtTowerResponse.d.ts +9 -5
- package/dist/src/udtTowerResponse.js +5 -6
- package/dist/src/udtTowerResponse.js.map +1 -1
- package/package.json +1 -1
package/dist/esm/index.mjs
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
var UART_SERVICE_UUID, UART_TX_CHARACTERISTIC_UUID, UART_RX_CHARACTERISTIC_UUID, TOWER_DEVICE_NAME, DIS_SERVICE_UUID, DIS_MANUFACTURER_NAME_UUID, DIS_MODEL_NUMBER_UUID, DIS_SERIAL_NUMBER_UUID, DIS_HARDWARE_REVISION_UUID, DIS_FIRMWARE_REVISION_UUID, DIS_SOFTWARE_REVISION_UUID, DIS_SYSTEM_ID_UUID, DIS_IEEE_REGULATORY_UUID, DIS_PNP_ID_UUID, TOWER_COMMAND_PACKET_SIZE, TOWER_STATE_DATA_SIZE, TOWER_COMMAND_HEADER_SIZE, TOWER_STATE_RESPONSE_MIN_LENGTH, TOWER_STATE_DATA_OFFSET, TOWER_COMMAND_TYPE_TOWER_STATE, DEFAULT_CONNECTION_MONITORING_FREQUENCY, DEFAULT_CONNECTION_MONITORING_TIMEOUT, DEFAULT_BATTERY_HEARTBEAT_TIMEOUT, BATTERY_STATUS_FREQUENCY, DEFAULT_RETRY_SEND_COMMAND_MAX, TOWER_SIDES_COUNT, TOWER_COMMANDS, TC, DRUM_PACKETS, GLYPHS, AUDIO_COMMAND_POS, SKULL_DROP_COUNT_POS, drumPositionCmds, LIGHT_EFFECTS, TOWER_LIGHT_SEQUENCES, TOWER_MESSAGES, VOLTAGE_LEVELS, TOWER_LAYERS, RING_LIGHT_POSITIONS, LEDGE_BASE_LIGHT_POSITIONS, LED_CHANNEL_LOOKUP, LAYER_TO_POSITION, LIGHT_INDEX_TO_DIRECTION, STATE_DATA_LENGTH, TOWER_AUDIO_LIBRARY, VOLUME_DESCRIPTIONS, VOLUME_ICONS;
|
|
31
31
|
var init_udtConstants = __esm({
|
|
32
32
|
"src/udtConstants.ts"() {
|
|
33
|
+
"use strict";
|
|
33
34
|
UART_SERVICE_UUID = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
|
|
34
35
|
UART_TX_CHARACTERISTIC_UUID = "6e400002-b5a3-f393-e0a9-e50e24dcca9e";
|
|
35
36
|
UART_RX_CHARACTERISTIC_UUID = "6e400003-b5a3-f393-e0a9-e50e24dcca9e";
|
|
@@ -361,160 +362,11 @@ var init_udtConstants = __esm({
|
|
|
361
362
|
}
|
|
362
363
|
});
|
|
363
364
|
|
|
364
|
-
// src/udtTowerState.ts
|
|
365
|
-
var udtTowerState_exports = {};
|
|
366
|
-
__export(udtTowerState_exports, {
|
|
367
|
-
LAYER_TO_POSITION: () => LAYER_TO_POSITION,
|
|
368
|
-
LEDGE_BASE_LIGHT_POSITIONS: () => LEDGE_BASE_LIGHT_POSITIONS,
|
|
369
|
-
LED_CHANNEL_LOOKUP: () => LED_CHANNEL_LOOKUP,
|
|
370
|
-
LIGHT_INDEX_TO_DIRECTION: () => LIGHT_INDEX_TO_DIRECTION,
|
|
371
|
-
RING_LIGHT_POSITIONS: () => RING_LIGHT_POSITIONS,
|
|
372
|
-
STATE_DATA_LENGTH: () => STATE_DATA_LENGTH,
|
|
373
|
-
TOWER_LAYERS: () => TOWER_LAYERS,
|
|
374
|
-
isCalibrated: () => isCalibrated,
|
|
375
|
-
rtdt_pack_state: () => rtdt_pack_state,
|
|
376
|
-
rtdt_unpack_state: () => rtdt_unpack_state
|
|
377
|
-
});
|
|
378
|
-
function rtdt_unpack_state(data) {
|
|
379
|
-
const state = {
|
|
380
|
-
drum: [
|
|
381
|
-
{ jammed: false, calibrated: false, position: 0, playSound: false, reverse: false },
|
|
382
|
-
{ jammed: false, calibrated: false, position: 0, playSound: false, reverse: false },
|
|
383
|
-
{ jammed: false, calibrated: false, position: 0, playSound: false, reverse: false }
|
|
384
|
-
],
|
|
385
|
-
layer: [
|
|
386
|
-
{ light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
|
|
387
|
-
{ light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
|
|
388
|
-
{ light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
|
|
389
|
-
{ light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
|
|
390
|
-
{ light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
|
|
391
|
-
{ light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] }
|
|
392
|
-
],
|
|
393
|
-
audio: { sample: 0, loop: false, volume: 0 },
|
|
394
|
-
beam: { count: 0, fault: false },
|
|
395
|
-
led_sequence: 0
|
|
396
|
-
};
|
|
397
|
-
state.drum[0].jammed = !!(data[0] & 8);
|
|
398
|
-
state.drum[0].calibrated = !!(data[0] & 16);
|
|
399
|
-
state.drum[1].jammed = !!(data[1] & 1);
|
|
400
|
-
state.drum[1].calibrated = !!(data[1] & 2);
|
|
401
|
-
state.drum[2].jammed = !!(data[1] & 32);
|
|
402
|
-
state.drum[2].calibrated = !!(data[1] & 64);
|
|
403
|
-
state.drum[0].position = (data[0] & 6) >> 1;
|
|
404
|
-
state.drum[1].position = (data[0] & 192) >> 6;
|
|
405
|
-
state.drum[2].position = (data[1] & 24) >> 3;
|
|
406
|
-
state.drum[0].playSound = !!(data[0] & 1);
|
|
407
|
-
state.drum[1].playSound = !!(data[0] & 32);
|
|
408
|
-
state.drum[2].playSound = !!(data[1] & 4);
|
|
409
|
-
state.layer[0].light[0].effect = (data[2] & 224) >> 5;
|
|
410
|
-
state.layer[0].light[0].loop = !!(data[2] & 16);
|
|
411
|
-
state.layer[0].light[1].effect = (data[2] & 14) >> 1;
|
|
412
|
-
state.layer[0].light[1].loop = !!(data[2] & 1);
|
|
413
|
-
state.layer[0].light[2].effect = (data[3] & 224) >> 5;
|
|
414
|
-
state.layer[0].light[2].loop = !!(data[3] & 16);
|
|
415
|
-
state.layer[0].light[3].effect = (data[3] & 14) >> 1;
|
|
416
|
-
state.layer[0].light[3].loop = !!(data[3] & 1);
|
|
417
|
-
state.layer[1].light[0].effect = (data[4] & 224) >> 5;
|
|
418
|
-
state.layer[1].light[0].loop = !!(data[4] & 16);
|
|
419
|
-
state.layer[1].light[1].effect = (data[4] & 14) >> 1;
|
|
420
|
-
state.layer[1].light[1].loop = !!(data[4] & 1);
|
|
421
|
-
state.layer[1].light[2].effect = (data[5] & 224) >> 5;
|
|
422
|
-
state.layer[1].light[2].loop = !!(data[5] & 16);
|
|
423
|
-
state.layer[1].light[3].effect = (data[5] & 14) >> 1;
|
|
424
|
-
state.layer[1].light[3].loop = !!(data[5] & 1);
|
|
425
|
-
state.layer[2].light[0].effect = (data[6] & 224) >> 5;
|
|
426
|
-
state.layer[2].light[0].loop = !!(data[6] & 16);
|
|
427
|
-
state.layer[2].light[1].effect = (data[6] & 14) >> 1;
|
|
428
|
-
state.layer[2].light[1].loop = !!(data[6] & 1);
|
|
429
|
-
state.layer[2].light[2].effect = (data[7] & 224) >> 5;
|
|
430
|
-
state.layer[2].light[2].loop = !!(data[7] & 16);
|
|
431
|
-
state.layer[2].light[3].effect = (data[7] & 14) >> 1;
|
|
432
|
-
state.layer[2].light[3].loop = !!(data[7] & 1);
|
|
433
|
-
state.layer[3].light[0].effect = (data[8] & 224) >> 5;
|
|
434
|
-
state.layer[3].light[0].loop = !!(data[8] & 16);
|
|
435
|
-
state.layer[3].light[1].effect = (data[8] & 14) >> 1;
|
|
436
|
-
state.layer[3].light[1].loop = !!(data[8] & 1);
|
|
437
|
-
state.layer[3].light[2].effect = (data[9] & 224) >> 5;
|
|
438
|
-
state.layer[3].light[2].loop = !!(data[9] & 16);
|
|
439
|
-
state.layer[3].light[3].effect = (data[9] & 14) >> 1;
|
|
440
|
-
state.layer[3].light[3].loop = !!(data[9] & 1);
|
|
441
|
-
state.layer[4].light[0].effect = (data[10] & 224) >> 5;
|
|
442
|
-
state.layer[4].light[0].loop = !!(data[10] & 16);
|
|
443
|
-
state.layer[4].light[1].effect = (data[10] & 14) >> 1;
|
|
444
|
-
state.layer[4].light[1].loop = !!(data[10] & 1);
|
|
445
|
-
state.layer[4].light[2].effect = (data[11] & 224) >> 5;
|
|
446
|
-
state.layer[4].light[2].loop = !!(data[11] & 16);
|
|
447
|
-
state.layer[4].light[3].effect = (data[11] & 14) >> 1;
|
|
448
|
-
state.layer[4].light[3].loop = !!(data[11] & 1);
|
|
449
|
-
state.layer[5].light[0].effect = (data[12] & 224) >> 5;
|
|
450
|
-
state.layer[5].light[0].loop = !!(data[12] & 16);
|
|
451
|
-
state.layer[5].light[1].effect = (data[12] & 14) >> 1;
|
|
452
|
-
state.layer[5].light[1].loop = !!(data[12] & 1);
|
|
453
|
-
state.layer[5].light[2].effect = (data[13] & 224) >> 5;
|
|
454
|
-
state.layer[5].light[2].loop = !!(data[13] & 16);
|
|
455
|
-
state.layer[5].light[3].effect = (data[13] & 14) >> 1;
|
|
456
|
-
state.layer[5].light[3].loop = !!(data[13] & 1);
|
|
457
|
-
state.audio.sample = data[14] & 127;
|
|
458
|
-
state.audio.loop = !!(data[14] & 128);
|
|
459
|
-
state.beam.count = data[15] << 8 | data[16];
|
|
460
|
-
state.beam.fault = !!(data[17] & 1);
|
|
461
|
-
state.drum[0].reverse = !!(data[17] & 2);
|
|
462
|
-
state.drum[1].reverse = !!(data[17] & 4);
|
|
463
|
-
state.drum[2].reverse = !!(data[17] & 8);
|
|
464
|
-
state.audio.volume = (data[17] & 240) >> 4;
|
|
465
|
-
state.led_sequence = data[18];
|
|
466
|
-
return state;
|
|
467
|
-
}
|
|
468
|
-
function rtdt_pack_state(data, len, state) {
|
|
469
|
-
if (!data || len < STATE_DATA_LENGTH)
|
|
470
|
-
return false;
|
|
471
|
-
data.fill(0, 0, STATE_DATA_LENGTH);
|
|
472
|
-
data[0] |= (state.drum[0].playSound ? 1 : 0) | (state.drum[0].position & 3) << 1 | (state.drum[0].jammed ? 1 : 0) << 3 | (state.drum[0].calibrated ? 1 : 0) << 4 | (state.drum[1].playSound ? 1 : 0) << 5 | (state.drum[1].position & 3) << 6;
|
|
473
|
-
data[1] |= (state.drum[1].jammed ? 1 : 0) | (state.drum[1].calibrated ? 1 : 0) << 1 | (state.drum[2].playSound ? 1 : 0) << 2 | (state.drum[2].position & 3) << 3 | (state.drum[2].jammed ? 1 : 0) << 5 | (state.drum[2].calibrated ? 1 : 0) << 6;
|
|
474
|
-
data[2] |= state.layer[0].light[0].effect << 5 | (state.layer[0].light[0].loop ? 1 : 0) << 4;
|
|
475
|
-
data[2] |= state.layer[0].light[1].effect << 1 | (state.layer[0].light[1].loop ? 1 : 0);
|
|
476
|
-
data[3] |= state.layer[0].light[2].effect << 5 | (state.layer[0].light[2].loop ? 1 : 0) << 4;
|
|
477
|
-
data[3] |= state.layer[0].light[3].effect << 1 | (state.layer[0].light[3].loop ? 1 : 0);
|
|
478
|
-
data[4] |= state.layer[1].light[0].effect << 5 | (state.layer[1].light[0].loop ? 1 : 0) << 4;
|
|
479
|
-
data[4] |= state.layer[1].light[1].effect << 1 | (state.layer[1].light[1].loop ? 1 : 0);
|
|
480
|
-
data[5] |= state.layer[1].light[2].effect << 5 | (state.layer[1].light[2].loop ? 1 : 0) << 4;
|
|
481
|
-
data[5] |= state.layer[1].light[3].effect << 1 | (state.layer[1].light[3].loop ? 1 : 0);
|
|
482
|
-
data[6] |= state.layer[2].light[0].effect << 5 | (state.layer[2].light[0].loop ? 1 : 0) << 4;
|
|
483
|
-
data[6] |= state.layer[2].light[1].effect << 1 | (state.layer[2].light[1].loop ? 1 : 0);
|
|
484
|
-
data[7] |= state.layer[2].light[2].effect << 5 | (state.layer[2].light[2].loop ? 1 : 0) << 4;
|
|
485
|
-
data[7] |= state.layer[2].light[3].effect << 1 | (state.layer[2].light[3].loop ? 1 : 0);
|
|
486
|
-
data[8] |= state.layer[3].light[0].effect << 5 | (state.layer[3].light[0].loop ? 1 : 0) << 4;
|
|
487
|
-
data[8] |= state.layer[3].light[1].effect << 1 | (state.layer[3].light[1].loop ? 1 : 0);
|
|
488
|
-
data[9] |= state.layer[3].light[2].effect << 5 | (state.layer[3].light[2].loop ? 1 : 0) << 4;
|
|
489
|
-
data[9] |= state.layer[3].light[3].effect << 1 | (state.layer[3].light[3].loop ? 1 : 0);
|
|
490
|
-
data[10] |= state.layer[4].light[0].effect << 5 | (state.layer[4].light[0].loop ? 1 : 0) << 4;
|
|
491
|
-
data[10] |= state.layer[4].light[1].effect << 1 | (state.layer[4].light[1].loop ? 1 : 0);
|
|
492
|
-
data[11] |= state.layer[4].light[2].effect << 5 | (state.layer[4].light[2].loop ? 1 : 0) << 4;
|
|
493
|
-
data[11] |= state.layer[4].light[3].effect << 1 | (state.layer[4].light[3].loop ? 1 : 0);
|
|
494
|
-
data[12] |= state.layer[5].light[0].effect << 5 | (state.layer[5].light[0].loop ? 1 : 0) << 4;
|
|
495
|
-
data[12] |= state.layer[5].light[1].effect << 1 | (state.layer[5].light[1].loop ? 1 : 0);
|
|
496
|
-
data[13] |= state.layer[5].light[2].effect << 5 | (state.layer[5].light[2].loop ? 1 : 0) << 4;
|
|
497
|
-
data[13] |= state.layer[5].light[3].effect << 1 | (state.layer[5].light[3].loop ? 1 : 0);
|
|
498
|
-
data[14] = state.audio.sample | (state.audio.loop ? 1 : 0) << 7;
|
|
499
|
-
data[15] = state.beam.count >> 8;
|
|
500
|
-
data[16] = state.beam.count & 255;
|
|
501
|
-
data[17] = state.audio.volume << 4 | (state.beam.fault ? 1 : 0) | (state.drum[0].reverse ? 1 : 0) << 1 | (state.drum[1].reverse ? 1 : 0) << 2 | (state.drum[2].reverse ? 1 : 0) << 3;
|
|
502
|
-
data[18] = state.led_sequence;
|
|
503
|
-
return true;
|
|
504
|
-
}
|
|
505
|
-
function isCalibrated(state) {
|
|
506
|
-
return state.drum.every((drum) => drum.calibrated);
|
|
507
|
-
}
|
|
508
|
-
var init_udtTowerState = __esm({
|
|
509
|
-
"src/udtTowerState.ts"() {
|
|
510
|
-
init_udtConstants();
|
|
511
|
-
}
|
|
512
|
-
});
|
|
513
|
-
|
|
514
365
|
// src/udtBluetoothAdapter.ts
|
|
515
366
|
var BluetoothError, BluetoothConnectionError, BluetoothDeviceNotFoundError, BluetoothUserCancelledError, BluetoothTimeoutError;
|
|
516
367
|
var init_udtBluetoothAdapter = __esm({
|
|
517
368
|
"src/udtBluetoothAdapter.ts"() {
|
|
369
|
+
"use strict";
|
|
518
370
|
BluetoothError = class extends Error {
|
|
519
371
|
constructor(message, originalError) {
|
|
520
372
|
super(message);
|
|
@@ -557,6 +409,7 @@ __export(WebBluetoothAdapter_exports, {
|
|
|
557
409
|
var WebBluetoothAdapter;
|
|
558
410
|
var init_WebBluetoothAdapter = __esm({
|
|
559
411
|
"src/adapters/WebBluetoothAdapter.ts"() {
|
|
412
|
+
"use strict";
|
|
560
413
|
init_udtConstants();
|
|
561
414
|
init_udtBluetoothAdapter();
|
|
562
415
|
WebBluetoothAdapter = class {
|
|
@@ -719,6 +572,7 @@ __export(NodeBluetoothAdapter_exports, {
|
|
|
719
572
|
var noble, NodeBluetoothAdapter;
|
|
720
573
|
var init_NodeBluetoothAdapter = __esm({
|
|
721
574
|
"src/adapters/NodeBluetoothAdapter.ts"() {
|
|
575
|
+
"use strict";
|
|
722
576
|
init_udtBluetoothAdapter();
|
|
723
577
|
init_udtConstants();
|
|
724
578
|
try {
|
|
@@ -1003,7 +857,139 @@ var init_NodeBluetoothAdapter = __esm({
|
|
|
1003
857
|
|
|
1004
858
|
// src/UltimateDarkTower.ts
|
|
1005
859
|
init_udtConstants();
|
|
1006
|
-
|
|
860
|
+
|
|
861
|
+
// src/udtTowerState.ts
|
|
862
|
+
init_udtConstants();
|
|
863
|
+
function rtdt_unpack_state(data) {
|
|
864
|
+
const state = {
|
|
865
|
+
drum: [
|
|
866
|
+
{ jammed: false, calibrated: false, position: 0, playSound: false, reverse: false },
|
|
867
|
+
{ jammed: false, calibrated: false, position: 0, playSound: false, reverse: false },
|
|
868
|
+
{ jammed: false, calibrated: false, position: 0, playSound: false, reverse: false }
|
|
869
|
+
],
|
|
870
|
+
layer: [
|
|
871
|
+
{ light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
|
|
872
|
+
{ light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
|
|
873
|
+
{ light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
|
|
874
|
+
{ light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
|
|
875
|
+
{ light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
|
|
876
|
+
{ light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] }
|
|
877
|
+
],
|
|
878
|
+
audio: { sample: 0, loop: false, volume: 0 },
|
|
879
|
+
beam: { count: 0, fault: false },
|
|
880
|
+
led_sequence: 0
|
|
881
|
+
};
|
|
882
|
+
state.drum[0].jammed = !!(data[0] & 8);
|
|
883
|
+
state.drum[0].calibrated = !!(data[0] & 16);
|
|
884
|
+
state.drum[1].jammed = !!(data[1] & 1);
|
|
885
|
+
state.drum[1].calibrated = !!(data[1] & 2);
|
|
886
|
+
state.drum[2].jammed = !!(data[1] & 32);
|
|
887
|
+
state.drum[2].calibrated = !!(data[1] & 64);
|
|
888
|
+
state.drum[0].position = (data[0] & 6) >> 1;
|
|
889
|
+
state.drum[1].position = (data[0] & 192) >> 6;
|
|
890
|
+
state.drum[2].position = (data[1] & 24) >> 3;
|
|
891
|
+
state.drum[0].playSound = !!(data[0] & 1);
|
|
892
|
+
state.drum[1].playSound = !!(data[0] & 32);
|
|
893
|
+
state.drum[2].playSound = !!(data[1] & 4);
|
|
894
|
+
state.layer[0].light[0].effect = (data[2] & 224) >> 5;
|
|
895
|
+
state.layer[0].light[0].loop = !!(data[2] & 16);
|
|
896
|
+
state.layer[0].light[1].effect = (data[2] & 14) >> 1;
|
|
897
|
+
state.layer[0].light[1].loop = !!(data[2] & 1);
|
|
898
|
+
state.layer[0].light[2].effect = (data[3] & 224) >> 5;
|
|
899
|
+
state.layer[0].light[2].loop = !!(data[3] & 16);
|
|
900
|
+
state.layer[0].light[3].effect = (data[3] & 14) >> 1;
|
|
901
|
+
state.layer[0].light[3].loop = !!(data[3] & 1);
|
|
902
|
+
state.layer[1].light[0].effect = (data[4] & 224) >> 5;
|
|
903
|
+
state.layer[1].light[0].loop = !!(data[4] & 16);
|
|
904
|
+
state.layer[1].light[1].effect = (data[4] & 14) >> 1;
|
|
905
|
+
state.layer[1].light[1].loop = !!(data[4] & 1);
|
|
906
|
+
state.layer[1].light[2].effect = (data[5] & 224) >> 5;
|
|
907
|
+
state.layer[1].light[2].loop = !!(data[5] & 16);
|
|
908
|
+
state.layer[1].light[3].effect = (data[5] & 14) >> 1;
|
|
909
|
+
state.layer[1].light[3].loop = !!(data[5] & 1);
|
|
910
|
+
state.layer[2].light[0].effect = (data[6] & 224) >> 5;
|
|
911
|
+
state.layer[2].light[0].loop = !!(data[6] & 16);
|
|
912
|
+
state.layer[2].light[1].effect = (data[6] & 14) >> 1;
|
|
913
|
+
state.layer[2].light[1].loop = !!(data[6] & 1);
|
|
914
|
+
state.layer[2].light[2].effect = (data[7] & 224) >> 5;
|
|
915
|
+
state.layer[2].light[2].loop = !!(data[7] & 16);
|
|
916
|
+
state.layer[2].light[3].effect = (data[7] & 14) >> 1;
|
|
917
|
+
state.layer[2].light[3].loop = !!(data[7] & 1);
|
|
918
|
+
state.layer[3].light[0].effect = (data[8] & 224) >> 5;
|
|
919
|
+
state.layer[3].light[0].loop = !!(data[8] & 16);
|
|
920
|
+
state.layer[3].light[1].effect = (data[8] & 14) >> 1;
|
|
921
|
+
state.layer[3].light[1].loop = !!(data[8] & 1);
|
|
922
|
+
state.layer[3].light[2].effect = (data[9] & 224) >> 5;
|
|
923
|
+
state.layer[3].light[2].loop = !!(data[9] & 16);
|
|
924
|
+
state.layer[3].light[3].effect = (data[9] & 14) >> 1;
|
|
925
|
+
state.layer[3].light[3].loop = !!(data[9] & 1);
|
|
926
|
+
state.layer[4].light[0].effect = (data[10] & 224) >> 5;
|
|
927
|
+
state.layer[4].light[0].loop = !!(data[10] & 16);
|
|
928
|
+
state.layer[4].light[1].effect = (data[10] & 14) >> 1;
|
|
929
|
+
state.layer[4].light[1].loop = !!(data[10] & 1);
|
|
930
|
+
state.layer[4].light[2].effect = (data[11] & 224) >> 5;
|
|
931
|
+
state.layer[4].light[2].loop = !!(data[11] & 16);
|
|
932
|
+
state.layer[4].light[3].effect = (data[11] & 14) >> 1;
|
|
933
|
+
state.layer[4].light[3].loop = !!(data[11] & 1);
|
|
934
|
+
state.layer[5].light[0].effect = (data[12] & 224) >> 5;
|
|
935
|
+
state.layer[5].light[0].loop = !!(data[12] & 16);
|
|
936
|
+
state.layer[5].light[1].effect = (data[12] & 14) >> 1;
|
|
937
|
+
state.layer[5].light[1].loop = !!(data[12] & 1);
|
|
938
|
+
state.layer[5].light[2].effect = (data[13] & 224) >> 5;
|
|
939
|
+
state.layer[5].light[2].loop = !!(data[13] & 16);
|
|
940
|
+
state.layer[5].light[3].effect = (data[13] & 14) >> 1;
|
|
941
|
+
state.layer[5].light[3].loop = !!(data[13] & 1);
|
|
942
|
+
state.audio.sample = data[14] & 127;
|
|
943
|
+
state.audio.loop = !!(data[14] & 128);
|
|
944
|
+
state.beam.count = data[15] << 8 | data[16];
|
|
945
|
+
state.beam.fault = !!(data[17] & 1);
|
|
946
|
+
state.drum[0].reverse = !!(data[17] & 2);
|
|
947
|
+
state.drum[1].reverse = !!(data[17] & 4);
|
|
948
|
+
state.drum[2].reverse = !!(data[17] & 8);
|
|
949
|
+
state.audio.volume = (data[17] & 240) >> 4;
|
|
950
|
+
state.led_sequence = data[18];
|
|
951
|
+
return state;
|
|
952
|
+
}
|
|
953
|
+
function rtdt_pack_state(data, len, state) {
|
|
954
|
+
if (!data || len < STATE_DATA_LENGTH)
|
|
955
|
+
return false;
|
|
956
|
+
data.fill(0, 0, STATE_DATA_LENGTH);
|
|
957
|
+
data[0] |= (state.drum[0].playSound ? 1 : 0) | (state.drum[0].position & 3) << 1 | (state.drum[0].jammed ? 1 : 0) << 3 | (state.drum[0].calibrated ? 1 : 0) << 4 | (state.drum[1].playSound ? 1 : 0) << 5 | (state.drum[1].position & 3) << 6;
|
|
958
|
+
data[1] |= (state.drum[1].jammed ? 1 : 0) | (state.drum[1].calibrated ? 1 : 0) << 1 | (state.drum[2].playSound ? 1 : 0) << 2 | (state.drum[2].position & 3) << 3 | (state.drum[2].jammed ? 1 : 0) << 5 | (state.drum[2].calibrated ? 1 : 0) << 6;
|
|
959
|
+
data[2] |= state.layer[0].light[0].effect << 5 | (state.layer[0].light[0].loop ? 1 : 0) << 4;
|
|
960
|
+
data[2] |= state.layer[0].light[1].effect << 1 | (state.layer[0].light[1].loop ? 1 : 0);
|
|
961
|
+
data[3] |= state.layer[0].light[2].effect << 5 | (state.layer[0].light[2].loop ? 1 : 0) << 4;
|
|
962
|
+
data[3] |= state.layer[0].light[3].effect << 1 | (state.layer[0].light[3].loop ? 1 : 0);
|
|
963
|
+
data[4] |= state.layer[1].light[0].effect << 5 | (state.layer[1].light[0].loop ? 1 : 0) << 4;
|
|
964
|
+
data[4] |= state.layer[1].light[1].effect << 1 | (state.layer[1].light[1].loop ? 1 : 0);
|
|
965
|
+
data[5] |= state.layer[1].light[2].effect << 5 | (state.layer[1].light[2].loop ? 1 : 0) << 4;
|
|
966
|
+
data[5] |= state.layer[1].light[3].effect << 1 | (state.layer[1].light[3].loop ? 1 : 0);
|
|
967
|
+
data[6] |= state.layer[2].light[0].effect << 5 | (state.layer[2].light[0].loop ? 1 : 0) << 4;
|
|
968
|
+
data[6] |= state.layer[2].light[1].effect << 1 | (state.layer[2].light[1].loop ? 1 : 0);
|
|
969
|
+
data[7] |= state.layer[2].light[2].effect << 5 | (state.layer[2].light[2].loop ? 1 : 0) << 4;
|
|
970
|
+
data[7] |= state.layer[2].light[3].effect << 1 | (state.layer[2].light[3].loop ? 1 : 0);
|
|
971
|
+
data[8] |= state.layer[3].light[0].effect << 5 | (state.layer[3].light[0].loop ? 1 : 0) << 4;
|
|
972
|
+
data[8] |= state.layer[3].light[1].effect << 1 | (state.layer[3].light[1].loop ? 1 : 0);
|
|
973
|
+
data[9] |= state.layer[3].light[2].effect << 5 | (state.layer[3].light[2].loop ? 1 : 0) << 4;
|
|
974
|
+
data[9] |= state.layer[3].light[3].effect << 1 | (state.layer[3].light[3].loop ? 1 : 0);
|
|
975
|
+
data[10] |= state.layer[4].light[0].effect << 5 | (state.layer[4].light[0].loop ? 1 : 0) << 4;
|
|
976
|
+
data[10] |= state.layer[4].light[1].effect << 1 | (state.layer[4].light[1].loop ? 1 : 0);
|
|
977
|
+
data[11] |= state.layer[4].light[2].effect << 5 | (state.layer[4].light[2].loop ? 1 : 0) << 4;
|
|
978
|
+
data[11] |= state.layer[4].light[3].effect << 1 | (state.layer[4].light[3].loop ? 1 : 0);
|
|
979
|
+
data[12] |= state.layer[5].light[0].effect << 5 | (state.layer[5].light[0].loop ? 1 : 0) << 4;
|
|
980
|
+
data[12] |= state.layer[5].light[1].effect << 1 | (state.layer[5].light[1].loop ? 1 : 0);
|
|
981
|
+
data[13] |= state.layer[5].light[2].effect << 5 | (state.layer[5].light[2].loop ? 1 : 0) << 4;
|
|
982
|
+
data[13] |= state.layer[5].light[3].effect << 1 | (state.layer[5].light[3].loop ? 1 : 0);
|
|
983
|
+
data[14] = state.audio.sample | (state.audio.loop ? 1 : 0) << 7;
|
|
984
|
+
data[15] = state.beam.count >> 8;
|
|
985
|
+
data[16] = state.beam.count & 255;
|
|
986
|
+
data[17] = state.audio.volume << 4 | (state.beam.fault ? 1 : 0) | (state.drum[0].reverse ? 1 : 0) << 1 | (state.drum[1].reverse ? 1 : 0) << 2 | (state.drum[2].reverse ? 1 : 0) << 3;
|
|
987
|
+
data[18] = state.led_sequence;
|
|
988
|
+
return true;
|
|
989
|
+
}
|
|
990
|
+
function isCalibrated(state) {
|
|
991
|
+
return state.drum.every((drum) => drum.calibrated);
|
|
992
|
+
}
|
|
1007
993
|
|
|
1008
994
|
// src/udtHelpers.ts
|
|
1009
995
|
init_udtConstants();
|
|
@@ -1134,10 +1120,28 @@ var DOMOutput = class {
|
|
|
1134
1120
|
write(level, message, timestamp) {
|
|
1135
1121
|
if (!this.container) return;
|
|
1136
1122
|
this.allEntries.push({ level, message, timestamp });
|
|
1123
|
+
let removedEntries = false;
|
|
1137
1124
|
while (this.allEntries.length > this.maxLines) {
|
|
1138
1125
|
this.allEntries.shift();
|
|
1126
|
+
removedEntries = true;
|
|
1127
|
+
}
|
|
1128
|
+
if (removedEntries) {
|
|
1129
|
+
this.refreshDisplay();
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
const enabledLevels = this.getEnabledLevelsFromCheckboxes();
|
|
1133
|
+
if (enabledLevels.has(level)) {
|
|
1134
|
+
const textFilter = this.getTextFilter();
|
|
1135
|
+
if (!textFilter || message.toLowerCase().includes(textFilter.toLowerCase())) {
|
|
1136
|
+
const timeStr = timestamp.toLocaleTimeString();
|
|
1137
|
+
const logLine = document.createElement("div");
|
|
1138
|
+
logLine.className = `log-line log-${level}`;
|
|
1139
|
+
logLine.textContent = `[${timeStr}] ${message}`;
|
|
1140
|
+
this.container.appendChild(logLine);
|
|
1141
|
+
this.container.scrollTop = this.container.scrollHeight;
|
|
1142
|
+
this.updateBufferSizeDisplay();
|
|
1143
|
+
}
|
|
1139
1144
|
}
|
|
1140
|
-
this.refreshDisplay();
|
|
1141
1145
|
}
|
|
1142
1146
|
refreshDisplay() {
|
|
1143
1147
|
if (!this.container) return;
|
|
@@ -1237,6 +1241,9 @@ var Logger = class _Logger {
|
|
|
1237
1241
|
addOutput(output) {
|
|
1238
1242
|
this.outputs.push(output);
|
|
1239
1243
|
}
|
|
1244
|
+
clearOutputs() {
|
|
1245
|
+
this.outputs = [];
|
|
1246
|
+
}
|
|
1240
1247
|
setMinLevel(level) {
|
|
1241
1248
|
this.enabledLevels = /* @__PURE__ */ new Set([level]);
|
|
1242
1249
|
}
|
|
@@ -1403,7 +1410,7 @@ var TowerResponseProcessor = class {
|
|
|
1403
1410
|
const cmdKey = cmdKeys.find((key) => TOWER_MESSAGES[key].value === cmdValue);
|
|
1404
1411
|
if (!cmdKey) {
|
|
1405
1412
|
logger.warn(`Unknown command received from tower: ${cmdValue} (0x${cmdValue.toString(16)})`, "TowerResponseProcessor");
|
|
1406
|
-
return { cmdKey: void 0, command: { name: "Unknown Command", value: cmdValue } };
|
|
1413
|
+
return { cmdKey: void 0, command: { name: "Unknown Command", value: cmdValue, critical: false } };
|
|
1407
1414
|
}
|
|
1408
1415
|
const command = TOWER_MESSAGES[cmdKey];
|
|
1409
1416
|
return { cmdKey, command };
|
|
@@ -1446,12 +1453,11 @@ var TowerResponseProcessor = class {
|
|
|
1446
1453
|
* @returns {boolean} Whether this response should be logged
|
|
1447
1454
|
*/
|
|
1448
1455
|
shouldLogResponse(cmdKey, logConfig) {
|
|
1449
|
-
const logAll = logConfig["LOG_ALL"];
|
|
1450
|
-
let canLogThisResponse = logConfig[cmdKey] || logAll;
|
|
1451
1456
|
if (!cmdKey) {
|
|
1452
|
-
|
|
1457
|
+
return true;
|
|
1453
1458
|
}
|
|
1454
|
-
|
|
1459
|
+
const logAll = logConfig["LOG_ALL"];
|
|
1460
|
+
return logConfig[cmdKey] || logAll;
|
|
1455
1461
|
}
|
|
1456
1462
|
/**
|
|
1457
1463
|
* Checks if a command is a battery response type.
|
|
@@ -1471,9 +1477,6 @@ var TowerResponseProcessor = class {
|
|
|
1471
1477
|
}
|
|
1472
1478
|
};
|
|
1473
1479
|
|
|
1474
|
-
// src/udtBleConnection.ts
|
|
1475
|
-
init_udtTowerState();
|
|
1476
|
-
|
|
1477
1480
|
// src/udtBluetoothAdapterFactory.ts
|
|
1478
1481
|
var BluetoothPlatform = /* @__PURE__ */ ((BluetoothPlatform3) => {
|
|
1479
1482
|
BluetoothPlatform3["WEB"] = "web";
|
|
@@ -1549,11 +1552,11 @@ var UdtBleConnection = class {
|
|
|
1549
1552
|
// When true, verifies connection before triggering disconnection on heartbeat timeout
|
|
1550
1553
|
// Tower state
|
|
1551
1554
|
this.towerSkullDropCount = -1;
|
|
1552
|
-
this.
|
|
1555
|
+
this.lastBatteryLog = 0;
|
|
1553
1556
|
this.lastBatteryPercentage = "";
|
|
1554
|
-
this.
|
|
1555
|
-
this.
|
|
1556
|
-
this.
|
|
1557
|
+
this.batteryLogFrequency = 15 * 1e3;
|
|
1558
|
+
this.batteryLogOnChangeOnly = false;
|
|
1559
|
+
this.batteryLogEnabled = true;
|
|
1557
1560
|
// Device information
|
|
1558
1561
|
this.deviceInformation = {};
|
|
1559
1562
|
// Logging configuration
|
|
@@ -1632,7 +1635,7 @@ var UdtBleConnection = class {
|
|
|
1632
1635
|
this.lastSuccessfulCommand = Date.now();
|
|
1633
1636
|
const { cmdKey } = this.responseProcessor.getTowerCommand(receivedData[0]);
|
|
1634
1637
|
const isBattery = this.responseProcessor.isBatteryResponse(cmdKey);
|
|
1635
|
-
const shouldLogCommand = this.logTowerResponses && this.responseProcessor.shouldLogResponse(cmdKey, this.logTowerResponseConfig) &&
|
|
1638
|
+
const shouldLogCommand = this.logTowerResponses && this.responseProcessor.shouldLogResponse(cmdKey, this.logTowerResponseConfig) && !isBattery;
|
|
1636
1639
|
if (shouldLogCommand) {
|
|
1637
1640
|
this.logger.info(`${cmdKey}`, "[UDT][BLE][RCVD]");
|
|
1638
1641
|
}
|
|
@@ -1647,14 +1650,14 @@ var UdtBleConnection = class {
|
|
|
1647
1650
|
const millivolts = getMilliVoltsFromTowerResponse(receivedData);
|
|
1648
1651
|
const batteryPercentage = milliVoltsToPercentage(millivolts);
|
|
1649
1652
|
const didBatteryLevelChange = this.lastBatteryPercentage !== "" && this.lastBatteryPercentage !== batteryPercentage;
|
|
1650
|
-
const
|
|
1651
|
-
const
|
|
1652
|
-
if (
|
|
1653
|
+
const batteryLogFrequencyPassed = Date.now() - this.lastBatteryLog >= this.batteryLogFrequency;
|
|
1654
|
+
const shouldLog = this.batteryLogEnabled && (this.batteryLogOnChangeOnly ? didBatteryLevelChange || this.lastBatteryPercentage === "" : batteryLogFrequencyPassed);
|
|
1655
|
+
if (shouldLog) {
|
|
1653
1656
|
this.logger.info(`${this.responseProcessor.commandToString(receivedData).join(" ")}`, "[UDT][BLE]");
|
|
1654
|
-
this.
|
|
1657
|
+
this.lastBatteryLog = Date.now();
|
|
1655
1658
|
this.lastBatteryPercentage = batteryPercentage;
|
|
1656
|
-
this.callbacks.onBatteryLevelNotify(millivolts);
|
|
1657
1659
|
}
|
|
1660
|
+
this.callbacks.onBatteryLevelNotify(millivolts);
|
|
1658
1661
|
} else {
|
|
1659
1662
|
if (this.callbacks.onTowerResponse) {
|
|
1660
1663
|
this.callbacks.onTowerResponse(receivedData);
|
|
@@ -1844,7 +1847,6 @@ var UdtBleConnection = class {
|
|
|
1844
1847
|
|
|
1845
1848
|
// src/udtCommandFactory.ts
|
|
1846
1849
|
init_udtConstants();
|
|
1847
|
-
init_udtTowerState();
|
|
1848
1850
|
var UdtCommandFactory = class {
|
|
1849
1851
|
/**
|
|
1850
1852
|
* Creates a rotation command packet for positioning tower drums.
|
|
@@ -1866,8 +1868,7 @@ var UdtCommandFactory = class {
|
|
|
1866
1868
|
*/
|
|
1867
1869
|
createSoundCommand(soundIndex) {
|
|
1868
1870
|
const soundCommand = new Uint8Array(TOWER_COMMAND_PACKET_SIZE);
|
|
1869
|
-
|
|
1870
|
-
soundCommand[AUDIO_COMMAND_POS] = sound;
|
|
1871
|
+
soundCommand[AUDIO_COMMAND_POS] = soundIndex & 255;
|
|
1871
1872
|
return soundCommand;
|
|
1872
1873
|
}
|
|
1873
1874
|
/**
|
|
@@ -1887,7 +1888,7 @@ var UdtCommandFactory = class {
|
|
|
1887
1888
|
* @returns 20-byte command packet (command type + 19-byte state data)
|
|
1888
1889
|
*/
|
|
1889
1890
|
createStatefulCommand(currentState, modifications) {
|
|
1890
|
-
const newState = currentState ?
|
|
1891
|
+
const newState = currentState ? this.deepCopyTowerState(currentState) : this.createEmptyTowerState();
|
|
1891
1892
|
if (modifications.drum) {
|
|
1892
1893
|
modifications.drum.forEach((drum, index) => {
|
|
1893
1894
|
if (drum && newState.drum[index]) {
|
|
@@ -1929,17 +1930,10 @@ var UdtCommandFactory = class {
|
|
|
1929
1930
|
* @returns 20-byte command packet
|
|
1930
1931
|
*/
|
|
1931
1932
|
createStatefulLEDCommand(currentState, layerIndex, lightIndex, effect, loop = false) {
|
|
1932
|
-
const
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
}
|
|
1936
|
-
if (!modifications.layer[layerIndex]) {
|
|
1937
|
-
modifications.layer[layerIndex] = { light: [] };
|
|
1938
|
-
}
|
|
1939
|
-
if (!modifications.layer[layerIndex].light) {
|
|
1940
|
-
modifications.layer[layerIndex].light = [];
|
|
1941
|
-
}
|
|
1942
|
-
modifications.layer[layerIndex].light[lightIndex] = { effect, loop };
|
|
1933
|
+
const layer = [];
|
|
1934
|
+
layer[layerIndex] = { light: [] };
|
|
1935
|
+
layer[layerIndex].light[lightIndex] = { effect, loop };
|
|
1936
|
+
const modifications = { layer };
|
|
1943
1937
|
modifications.audio = { sample: 0, loop: false, volume: 0 };
|
|
1944
1938
|
return this.createStatefulCommand(currentState, modifications);
|
|
1945
1939
|
}
|
|
@@ -2033,17 +2027,15 @@ var UdtCommandFactory = class {
|
|
|
2033
2027
|
* @returns 20-byte command packet
|
|
2034
2028
|
*/
|
|
2035
2029
|
createStatefulDrumCommand(currentState, drumIndex, position, playSound = false) {
|
|
2036
|
-
const
|
|
2037
|
-
|
|
2038
|
-
modifications.drum = [];
|
|
2039
|
-
}
|
|
2040
|
-
modifications.drum[drumIndex] = {
|
|
2030
|
+
const drum = [];
|
|
2031
|
+
drum[drumIndex] = {
|
|
2041
2032
|
jammed: false,
|
|
2042
2033
|
calibrated: true,
|
|
2043
2034
|
position,
|
|
2044
2035
|
playSound,
|
|
2045
2036
|
reverse: false
|
|
2046
2037
|
};
|
|
2038
|
+
const modifications = { drum };
|
|
2047
2039
|
modifications.audio = { sample: 0, loop: false, volume: 0 };
|
|
2048
2040
|
return this.createStatefulCommand(currentState, modifications);
|
|
2049
2041
|
}
|
|
@@ -2087,6 +2079,22 @@ var UdtCommandFactory = class {
|
|
|
2087
2079
|
led_sequence: 0
|
|
2088
2080
|
};
|
|
2089
2081
|
}
|
|
2082
|
+
/**
|
|
2083
|
+
* Creates a deep copy of a TowerState to avoid mutating the original.
|
|
2084
|
+
* @param state - The tower state to copy
|
|
2085
|
+
* @returns A new TowerState with all nested objects copied
|
|
2086
|
+
*/
|
|
2087
|
+
deepCopyTowerState(state) {
|
|
2088
|
+
return {
|
|
2089
|
+
drum: state.drum.map((d) => ({ ...d })),
|
|
2090
|
+
layer: state.layer.map((l) => ({
|
|
2091
|
+
light: l.light.map((lt) => ({ ...lt }))
|
|
2092
|
+
})),
|
|
2093
|
+
audio: { ...state.audio },
|
|
2094
|
+
beam: { ...state.beam },
|
|
2095
|
+
led_sequence: state.led_sequence
|
|
2096
|
+
};
|
|
2097
|
+
}
|
|
2090
2098
|
//#endregion
|
|
2091
2099
|
};
|
|
2092
2100
|
|
|
@@ -2170,9 +2178,10 @@ var CommandQueue = class {
|
|
|
2170
2178
|
if (this.currentCommand) {
|
|
2171
2179
|
const { description, id } = this.currentCommand;
|
|
2172
2180
|
this.logger.warn(`Command timeout after ${this.timeoutMs}ms: ${description || id}`, "[UDT]");
|
|
2173
|
-
this.currentCommand.
|
|
2181
|
+
const reject = this.currentCommand.reject;
|
|
2174
2182
|
this.currentCommand = null;
|
|
2175
2183
|
this.isProcessing = false;
|
|
2184
|
+
reject(new Error(`Command timeout after ${this.timeoutMs}ms: ${description || id}`));
|
|
2176
2185
|
this.processNext();
|
|
2177
2186
|
}
|
|
2178
2187
|
}
|
|
@@ -2254,7 +2263,7 @@ var UdtTowerCommands = class {
|
|
|
2254
2263
|
this.deps.bleConnection.lastSuccessfulCommand = Date.now();
|
|
2255
2264
|
} catch (error) {
|
|
2256
2265
|
this.deps.logger.error(`command send error: ${error}`, "[UDT][CMD]");
|
|
2257
|
-
const errorMsg = error?.message ??
|
|
2266
|
+
const errorMsg = error?.message ?? String(error);
|
|
2258
2267
|
const wasCancelled = errorMsg.includes("User cancelled");
|
|
2259
2268
|
const maxRetriesReached = this.deps.retrySendCommandCount.value >= this.deps.retrySendCommandMax;
|
|
2260
2269
|
const isDisconnected = errorMsg.includes("Cannot read properties of null") || errorMsg.includes("GATT Server is disconnected") || errorMsg.includes("Device is not connected") || errorMsg.includes("BluetoothConnectionError") || !this.deps.bleConnection.isConnected;
|
|
@@ -2266,9 +2275,9 @@ var UdtTowerCommands = class {
|
|
|
2266
2275
|
if (!maxRetriesReached && this.deps.bleConnection.isConnected && !wasCancelled) {
|
|
2267
2276
|
this.deps.logger.info(`retrying tower command attempt ${this.deps.retrySendCommandCount.value + 1}`, "[UDT][CMD]");
|
|
2268
2277
|
this.deps.retrySendCommandCount.value++;
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2278
|
+
const delay = 250 * this.deps.retrySendCommandCount.value;
|
|
2279
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
2280
|
+
return await this.sendTowerCommandDirect(command);
|
|
2272
2281
|
} else {
|
|
2273
2282
|
this.deps.retrySendCommandCount.value = 0;
|
|
2274
2283
|
}
|
|
@@ -2316,9 +2325,13 @@ var UdtTowerCommands = class {
|
|
|
2316
2325
|
this.deps.logDetail && this.deps.logger.debug(`Light Parameter ${JSON.stringify(lights)}`, "[UDT][CMD]");
|
|
2317
2326
|
this.deps.logger.info("Sending light commands", "[UDT][CMD]");
|
|
2318
2327
|
const layerCommands = this.mapLightsToLayerCommands(lights);
|
|
2319
|
-
|
|
2320
|
-
|
|
2328
|
+
const currentState = this.deps.getCurrentTowerState();
|
|
2329
|
+
for (const { layerIndex, lightIndex, effect, loop } of layerCommands) {
|
|
2330
|
+
currentState.layer[layerIndex].light[lightIndex] = { effect, loop };
|
|
2321
2331
|
}
|
|
2332
|
+
const command = this.deps.commandFactory.createStatefulCommand(currentState, {});
|
|
2333
|
+
this.deps.setTowerState(currentState, "lights");
|
|
2334
|
+
await this.sendTowerCommand(command, "lights");
|
|
2322
2335
|
}
|
|
2323
2336
|
/**
|
|
2324
2337
|
* Maps the Lights object to layer/light index commands for setLEDStateful.
|
|
@@ -2332,7 +2345,7 @@ var UdtTowerCommands = class {
|
|
|
2332
2345
|
const layerIndex = this.getTowerLayerForLevel(doorwayLight.level);
|
|
2333
2346
|
const lightIndex = this.getLightIndexForSide(doorwayLight.position);
|
|
2334
2347
|
const effect = LIGHT_EFFECTS[doorwayLight.style] || LIGHT_EFFECTS.off;
|
|
2335
|
-
commands.push({ layerIndex, lightIndex, effect, loop:
|
|
2348
|
+
commands.push({ layerIndex, lightIndex, effect, loop: effect !== LIGHT_EFFECTS.off });
|
|
2336
2349
|
}
|
|
2337
2350
|
}
|
|
2338
2351
|
if (lights.ledge) {
|
|
@@ -2340,7 +2353,7 @@ var UdtTowerCommands = class {
|
|
|
2340
2353
|
const layerIndex = TOWER_LAYERS.LEDGE;
|
|
2341
2354
|
const lightIndex = this.getLedgeLightIndexForSide(ledgeLight.position);
|
|
2342
2355
|
const effect = LIGHT_EFFECTS[ledgeLight.style] || LIGHT_EFFECTS.off;
|
|
2343
|
-
commands.push({ layerIndex, lightIndex, effect, loop:
|
|
2356
|
+
commands.push({ layerIndex, lightIndex, effect, loop: effect !== LIGHT_EFFECTS.off });
|
|
2344
2357
|
}
|
|
2345
2358
|
}
|
|
2346
2359
|
if (lights.base) {
|
|
@@ -2348,7 +2361,7 @@ var UdtTowerCommands = class {
|
|
|
2348
2361
|
const layerIndex = baseLight.position.level === "top" || baseLight.position.level === "b" ? TOWER_LAYERS.BASE2 : TOWER_LAYERS.BASE1;
|
|
2349
2362
|
const lightIndex = this.getBaseLightIndexForSide(baseLight.position.side);
|
|
2350
2363
|
const effect = LIGHT_EFFECTS[baseLight.style] || LIGHT_EFFECTS.off;
|
|
2351
|
-
commands.push({ layerIndex, lightIndex, effect, loop:
|
|
2364
|
+
commands.push({ layerIndex, lightIndex, effect, loop: effect !== LIGHT_EFFECTS.off });
|
|
2352
2365
|
}
|
|
2353
2366
|
}
|
|
2354
2367
|
return commands;
|
|
@@ -2554,8 +2567,7 @@ var UdtTowerCommands = class {
|
|
|
2554
2567
|
};
|
|
2555
2568
|
const command = this.deps.commandFactory.createStatefulCommand(currentState, modifications);
|
|
2556
2569
|
await this.sendTowerCommand(command, "resetTowerSkullCount");
|
|
2557
|
-
const updatedState = { ...currentState };
|
|
2558
|
-
updatedState.beam.count = 0;
|
|
2570
|
+
const updatedState = { ...currentState, beam: { ...currentState.beam, count: 0 } };
|
|
2559
2571
|
this.deps.setTowerState(updatedState, "resetTowerSkullCount");
|
|
2560
2572
|
}
|
|
2561
2573
|
/**
|
|
@@ -2985,23 +2997,23 @@ var UltimateDarkTower = class {
|
|
|
2985
2997
|
return this.previousBatteryPercentage;
|
|
2986
2998
|
}
|
|
2987
2999
|
// Getter/setter methods for connection configuration
|
|
2988
|
-
get
|
|
2989
|
-
return this.bleConnection.
|
|
3000
|
+
get batteryLogFrequency() {
|
|
3001
|
+
return this.bleConnection.batteryLogFrequency;
|
|
2990
3002
|
}
|
|
2991
|
-
set
|
|
2992
|
-
this.bleConnection.
|
|
3003
|
+
set batteryLogFrequency(value) {
|
|
3004
|
+
this.bleConnection.batteryLogFrequency = value;
|
|
2993
3005
|
}
|
|
2994
|
-
get
|
|
2995
|
-
return this.bleConnection.
|
|
3006
|
+
get batteryLogOnChangeOnly() {
|
|
3007
|
+
return this.bleConnection.batteryLogOnChangeOnly;
|
|
2996
3008
|
}
|
|
2997
|
-
set
|
|
2998
|
-
this.bleConnection.
|
|
3009
|
+
set batteryLogOnChangeOnly(value) {
|
|
3010
|
+
this.bleConnection.batteryLogOnChangeOnly = value;
|
|
2999
3011
|
}
|
|
3000
|
-
get
|
|
3001
|
-
return this.bleConnection.
|
|
3012
|
+
get batteryLogEnabled() {
|
|
3013
|
+
return this.bleConnection.batteryLogEnabled;
|
|
3002
3014
|
}
|
|
3003
|
-
set
|
|
3004
|
-
this.bleConnection.
|
|
3015
|
+
set batteryLogEnabled(value) {
|
|
3016
|
+
this.bleConnection.batteryLogEnabled = value;
|
|
3005
3017
|
}
|
|
3006
3018
|
get logTowerResponses() {
|
|
3007
3019
|
return this.bleConnection.logTowerResponses;
|
|
@@ -3185,11 +3197,10 @@ var UltimateDarkTower = class {
|
|
|
3185
3197
|
* @returns Promise that resolves when the command is sent
|
|
3186
3198
|
*/
|
|
3187
3199
|
async sendTowerState(towerState) {
|
|
3188
|
-
const { rtdt_pack_state: rtdt_pack_state2 } = await Promise.resolve().then(() => (init_udtTowerState(), udtTowerState_exports));
|
|
3189
3200
|
const stateToSend = { ...towerState };
|
|
3190
3201
|
stateToSend.audio = { sample: 0, loop: false, volume: 0 };
|
|
3191
3202
|
const stateData = new Uint8Array(TOWER_STATE_DATA_SIZE);
|
|
3192
|
-
const success =
|
|
3203
|
+
const success = rtdt_pack_state(stateData, TOWER_STATE_DATA_SIZE, stateToSend);
|
|
3193
3204
|
if (!success) {
|
|
3194
3205
|
throw new Error("Failed to pack tower state data");
|
|
3195
3206
|
}
|
|
@@ -3217,11 +3228,9 @@ var UltimateDarkTower = class {
|
|
|
3217
3228
|
* @param stateData - The 19-byte state data from tower response
|
|
3218
3229
|
*/
|
|
3219
3230
|
updateTowerStateFromResponse(stateData) {
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
this.setTowerState(newState, "tower response");
|
|
3224
|
-
});
|
|
3231
|
+
const newState = rtdt_unpack_state(stateData);
|
|
3232
|
+
newState.audio = { sample: 0, loop: false, volume: this.currentTowerState.audio.volume };
|
|
3233
|
+
this.setTowerState(newState, "tower response");
|
|
3225
3234
|
}
|
|
3226
3235
|
//#endregion
|
|
3227
3236
|
/**
|
|
@@ -3449,7 +3458,7 @@ var UltimateDarkTower = class {
|
|
|
3449
3458
|
* @param {LogOutput[]} outputs - Array of log outputs to use (e.g., ConsoleOutput, DOMOutput)
|
|
3450
3459
|
*/
|
|
3451
3460
|
setLoggerOutputs(outputs) {
|
|
3452
|
-
this.logger.
|
|
3461
|
+
this.logger.clearOutputs();
|
|
3453
3462
|
outputs.forEach((output) => this.logger.addOutput(output));
|
|
3454
3463
|
}
|
|
3455
3464
|
/**
|
|
@@ -3547,7 +3556,6 @@ var UltimateDarkTower_default = UltimateDarkTower;
|
|
|
3547
3556
|
// src/index.ts
|
|
3548
3557
|
init_udtConstants();
|
|
3549
3558
|
init_udtBluetoothAdapter();
|
|
3550
|
-
init_udtTowerState();
|
|
3551
3559
|
var index_default = UltimateDarkTower_default;
|
|
3552
3560
|
export {
|
|
3553
3561
|
AUDIO_COMMAND_POS,
|