ultimatedarktower 1.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.
Files changed (36) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +138 -0
  3. package/dist/src/UltimateDarkTower.d.ts +379 -0
  4. package/dist/src/UltimateDarkTower.js +728 -0
  5. package/dist/src/UltimateDarkTower.js.map +1 -0
  6. package/dist/src/index.d.ts +10 -0
  7. package/dist/src/index.js +40 -0
  8. package/dist/src/index.js.map +1 -0
  9. package/dist/src/udtBleConnection.d.ts +96 -0
  10. package/dist/src/udtBleConnection.js +412 -0
  11. package/dist/src/udtBleConnection.js.map +1 -0
  12. package/dist/src/udtCommandFactory.d.ts +98 -0
  13. package/dist/src/udtCommandFactory.js +263 -0
  14. package/dist/src/udtCommandFactory.js.map +1 -0
  15. package/dist/src/udtCommandQueue.d.ts +51 -0
  16. package/dist/src/udtCommandQueue.js +143 -0
  17. package/dist/src/udtCommandQueue.js.map +1 -0
  18. package/dist/src/udtConstants.d.ts +278 -0
  19. package/dist/src/udtConstants.js +315 -0
  20. package/dist/src/udtConstants.js.map +1 -0
  21. package/dist/src/udtHelpers.d.ts +82 -0
  22. package/dist/src/udtHelpers.js +187 -0
  23. package/dist/src/udtHelpers.js.map +1 -0
  24. package/dist/src/udtLogger.d.ts +76 -0
  25. package/dist/src/udtLogger.js +344 -0
  26. package/dist/src/udtLogger.js.map +1 -0
  27. package/dist/src/udtTowerCommands.d.ts +210 -0
  28. package/dist/src/udtTowerCommands.js +620 -0
  29. package/dist/src/udtTowerCommands.js.map +1 -0
  30. package/dist/src/udtTowerResponse.d.ts +43 -0
  31. package/dist/src/udtTowerResponse.js +98 -0
  32. package/dist/src/udtTowerResponse.js.map +1 -0
  33. package/dist/src/udtTowerState.d.ts +59 -0
  34. package/dist/src/udtTowerState.js +198 -0
  35. package/dist/src/udtTowerState.js.map +1 -0
  36. package/package.json +90 -0
@@ -0,0 +1,82 @@
1
+ import { type TowerState } from './udtTowerState';
2
+ /**
3
+ * Converts battery voltage in millivolts to percentage number (0-100).
4
+ * @param mv - Battery voltage in millivolts
5
+ * @returns Battery percentage as number (0-100)
6
+ */
7
+ export declare function milliVoltsToPercentageNumber(mv: number): number;
8
+ /**
9
+ * Converts battery voltage in millivolts to percentage.
10
+ * Tower returns sum total battery level in millivolts for all batteries.
11
+ * @param mv - Battery voltage in millivolts
12
+ * @returns Battery percentage as formatted string (e.g., "75%")
13
+ */
14
+ export declare function milliVoltsToPercentage(mv: number): string;
15
+ /**
16
+ * Extracts battery voltage in millivolts from a tower battery response.
17
+ * @param {Uint8Array} command - Battery response packet from tower
18
+ * @returns {number} Battery voltage in millivolts
19
+ */
20
+ export declare function getMilliVoltsFromTowerResponse(command: Uint8Array): number;
21
+ /**
22
+ * Converts a command packet to a hex string representation for debugging.
23
+ * @param {Uint8Array} command - Command packet to convert
24
+ * @returns {string} Hex string representation of the command packet
25
+ */
26
+ export declare function commandToPacketString(command: Uint8Array): string;
27
+ /**
28
+ * Utility function to get the tower position and direction for a given layer and light index
29
+ * Updated based on LED channel lookup table and corrected architecture:
30
+ * - Layers 0-2: Ring LEDs with cardinal directions (N,E,S,W)
31
+ * - Layers 3-5: Ledge/Base LEDs with ordinal directions (NE,SE,SW,NW)
32
+ * @param layerIndex - The layer index (0-5)
33
+ * @param lightIndex - The light index within the layer (0-3)
34
+ * @returns Object containing the tower level, direction, and LED channel
35
+ */
36
+ export declare function getTowerPosition(layerIndex: number, lightIndex: number): {
37
+ level: string;
38
+ direction: string;
39
+ ledChannel?: number;
40
+ };
41
+ /**
42
+ * Utility function to get all active lights in a tower state
43
+ * @param state - The tower state object
44
+ * @returns Array of objects describing each active light
45
+ */
46
+ export declare function getActiveLights(state: TowerState): Array<{
47
+ level: string;
48
+ direction: string;
49
+ effect: number;
50
+ loop: boolean;
51
+ }>;
52
+ /**
53
+ * Interface for parsed differential readings
54
+ */
55
+ export interface ParsedDifferentialReadings {
56
+ irBeam: number;
57
+ drum1: number;
58
+ drum2: number;
59
+ drum3: number;
60
+ timestamp: number;
61
+ rawData: Uint8Array;
62
+ }
63
+ /**
64
+ * Parses a tower response containing differential readings into individual components.
65
+ * The firmware packs 4 differential readings into a 32-bit value and transmits as bytes:
66
+ * - Firmware: (signals_smoothed[0] << 24) | (signals_smoothed[1] << 16) | (signals_smoothed[2] << 8) | signals_smoothed[3]
67
+ * - signals_smoothed[0] = IR beam (drop sensor)
68
+ * - signals_smoothed[1] = Drum 1 (top)
69
+ * - signals_smoothed[2] = Drum 2 (middle)
70
+ * - signals_smoothed[3] = Drum 3 (bottom)
71
+ *
72
+ * Transmitted as: [cmd_byte][IR_beam][drum1][drum2][drum3]
73
+ *
74
+ * @param response - Tower response packet (should be MESSAGE_DIFFERENTIAL_READINGS with command value 6)
75
+ * @returns Parsed differential readings or null if not a valid differential response
76
+ */
77
+ export declare function parseDifferentialReadings(response: Uint8Array): ParsedDifferentialReadings | null;
78
+ /**
79
+ * Creates a default/empty tower state with all settings reset to defaults
80
+ * @returns A default TowerState object with all lights off, no audio, etc.
81
+ */
82
+ export declare function createDefaultTowerState(): TowerState;
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDefaultTowerState = exports.parseDifferentialReadings = exports.getActiveLights = exports.getTowerPosition = exports.commandToPacketString = exports.getMilliVoltsFromTowerResponse = exports.milliVoltsToPercentage = exports.milliVoltsToPercentageNumber = void 0;
4
+ const udtConstants_1 = require("./udtConstants");
5
+ /**
6
+ * Internal function to calculate battery percentage from millivolts.
7
+ * @param mv - Battery voltage in millivolts
8
+ * @returns Battery percentage as number (0-100)
9
+ */
10
+ function calculateBatteryPercentage(mv) {
11
+ const batLevel = mv ? mv / 3 : 0; // lookup is based on single AA
12
+ const levels = udtConstants_1.VOLTAGE_LEVELS.filter(v => batLevel >= v);
13
+ return levels.length * 5;
14
+ }
15
+ /**
16
+ * Converts battery voltage in millivolts to percentage number (0-100).
17
+ * @param mv - Battery voltage in millivolts
18
+ * @returns Battery percentage as number (0-100)
19
+ */
20
+ function milliVoltsToPercentageNumber(mv) {
21
+ return calculateBatteryPercentage(mv);
22
+ }
23
+ exports.milliVoltsToPercentageNumber = milliVoltsToPercentageNumber;
24
+ /**
25
+ * Converts battery voltage in millivolts to percentage.
26
+ * Tower returns sum total battery level in millivolts for all batteries.
27
+ * @param mv - Battery voltage in millivolts
28
+ * @returns Battery percentage as formatted string (e.g., "75%")
29
+ */
30
+ function milliVoltsToPercentage(mv) {
31
+ return `${calculateBatteryPercentage(mv)}%`;
32
+ }
33
+ exports.milliVoltsToPercentage = milliVoltsToPercentage;
34
+ /**
35
+ * Extracts battery voltage in millivolts from a tower battery response.
36
+ * @param {Uint8Array} command - Battery response packet from tower
37
+ * @returns {number} Battery voltage in millivolts
38
+ */
39
+ function getMilliVoltsFromTowerResponse(command) {
40
+ const mv = new Uint8Array(4);
41
+ mv[0] = command[4];
42
+ mv[1] = command[3];
43
+ mv[2] = 0;
44
+ mv[3] = 0;
45
+ const view = new DataView(mv.buffer, 0);
46
+ return view.getUint32(0, true);
47
+ }
48
+ exports.getMilliVoltsFromTowerResponse = getMilliVoltsFromTowerResponse;
49
+ /**
50
+ * Converts a command packet to a hex string representation for debugging.
51
+ * @param {Uint8Array} command - Command packet to convert
52
+ * @returns {string} Hex string representation of the command packet
53
+ */
54
+ function commandToPacketString(command) {
55
+ if (command.length === 0) {
56
+ return "[]";
57
+ }
58
+ let cmdStr = "[";
59
+ command.forEach(n => cmdStr += n.toString(16) + ",");
60
+ cmdStr = cmdStr.slice(0, -1) + "]";
61
+ return cmdStr;
62
+ }
63
+ exports.commandToPacketString = commandToPacketString;
64
+ /**
65
+ * Utility function to get the tower position and direction for a given layer and light index
66
+ * Updated based on LED channel lookup table and corrected architecture:
67
+ * - Layers 0-2: Ring LEDs with cardinal directions (N,E,S,W)
68
+ * - Layers 3-5: Ledge/Base LEDs with ordinal directions (NE,SE,SW,NW)
69
+ * @param layerIndex - The layer index (0-5)
70
+ * @param lightIndex - The light index within the layer (0-3)
71
+ * @returns Object containing the tower level, direction, and LED channel
72
+ */
73
+ function getTowerPosition(layerIndex, lightIndex) {
74
+ const isRingLayer = layerIndex <= 2;
75
+ const ledChannel = udtConstants_1.LED_CHANNEL_LOOKUP[layerIndex * 4 + lightIndex];
76
+ if (isRingLayer) {
77
+ // Ring layers: cardinal directions (position 0 = North)
78
+ const directions = ['NORTH', 'EAST', 'SOUTH', 'WEST'];
79
+ const layerNames = ['TOP_RING', 'MIDDLE_RING', 'BOTTOM_RING'];
80
+ return {
81
+ level: layerNames[layerIndex],
82
+ direction: directions[lightIndex],
83
+ ledChannel
84
+ };
85
+ }
86
+ else {
87
+ // Ledge/Base layers: ordinal directions (position 0 = North-East)
88
+ const directions = ['NORTH_EAST', 'SOUTH_EAST', 'SOUTH_WEST', 'NORTH_WEST'];
89
+ const layerNames = ['LEDGE', 'BASE1', 'BASE2'];
90
+ return {
91
+ level: layerNames[layerIndex - 3],
92
+ direction: directions[lightIndex],
93
+ ledChannel
94
+ };
95
+ }
96
+ }
97
+ exports.getTowerPosition = getTowerPosition;
98
+ /**
99
+ * Utility function to get all active lights in a tower state
100
+ * @param state - The tower state object
101
+ * @returns Array of objects describing each active light
102
+ */
103
+ function getActiveLights(state) {
104
+ const activeLights = [];
105
+ state.layer.forEach((layer, layerIndex) => {
106
+ layer.light.forEach((light, lightIndex) => {
107
+ if (light.effect > 0) {
108
+ const position = getTowerPosition(layerIndex, lightIndex);
109
+ activeLights.push({
110
+ level: position.level,
111
+ direction: position.direction,
112
+ effect: light.effect,
113
+ loop: light.loop
114
+ });
115
+ }
116
+ });
117
+ });
118
+ return activeLights;
119
+ }
120
+ exports.getActiveLights = getActiveLights;
121
+ /**
122
+ * Parses a tower response containing differential readings into individual components.
123
+ * The firmware packs 4 differential readings into a 32-bit value and transmits as bytes:
124
+ * - Firmware: (signals_smoothed[0] << 24) | (signals_smoothed[1] << 16) | (signals_smoothed[2] << 8) | signals_smoothed[3]
125
+ * - signals_smoothed[0] = IR beam (drop sensor)
126
+ * - signals_smoothed[1] = Drum 1 (top)
127
+ * - signals_smoothed[2] = Drum 2 (middle)
128
+ * - signals_smoothed[3] = Drum 3 (bottom)
129
+ *
130
+ * Transmitted as: [cmd_byte][IR_beam][drum1][drum2][drum3]
131
+ *
132
+ * @param response - Tower response packet (should be MESSAGE_DIFFERENTIAL_READINGS with command value 6)
133
+ * @returns Parsed differential readings or null if not a valid differential response
134
+ */
135
+ function parseDifferentialReadings(response) {
136
+ // Check if this is a differential readings response (command value 6)
137
+ if (response.length < 5 || response[0] !== 6) {
138
+ return null;
139
+ }
140
+ // Based on debug output, the packet format is: [cmd][unknown/saturated][drum1][drum2][drum3]
141
+ // The 0xff (255) in byte 1 appears to be either a saturated value or different data
142
+ // The actual drum readings are in bytes 2, 3, 4 matching your log data
143
+ // Looking at your data pattern: "D1: 2, D2: 0, D3: 0" matches bytes [0x02, 0x00, 0x00]
144
+ // This suggests the IR beam might be calculated differently or is in a different position
145
+ // For now, let's extract what we can identify from the pattern:
146
+ const drum1 = response[2]; // Drum 1 - matches your "D1: 2"
147
+ const drum2 = response[3]; // Drum 2 - matches your "D2: 0"
148
+ const drum3 = response[4]; // Drum 3 - matches your "D3: 0"
149
+ // The IR beam (drop sensor) might be derived differently or require calibration
150
+ // For now, we'll use byte 1 but this needs further investigation
151
+ const irBeam = response[1]; // This is the 255 value - might be saturated/inverted
152
+ return {
153
+ irBeam,
154
+ drum1,
155
+ drum2,
156
+ drum3,
157
+ timestamp: Date.now(),
158
+ rawData: new Uint8Array(response)
159
+ };
160
+ }
161
+ exports.parseDifferentialReadings = parseDifferentialReadings;
162
+ /**
163
+ * Creates a default/empty tower state with all settings reset to defaults
164
+ * @returns A default TowerState object with all lights off, no audio, etc.
165
+ */
166
+ function createDefaultTowerState() {
167
+ return {
168
+ drum: [
169
+ { jammed: false, calibrated: false, position: 0, playSound: false, reverse: false },
170
+ { jammed: false, calibrated: false, position: 0, playSound: false, reverse: false },
171
+ { jammed: false, calibrated: false, position: 0, playSound: false, reverse: false }
172
+ ],
173
+ layer: [
174
+ { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
175
+ { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
176
+ { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
177
+ { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
178
+ { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
179
+ { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] }
180
+ ],
181
+ audio: { sample: 0, loop: false, volume: 0 },
182
+ beam: { count: 0, fault: false },
183
+ led_sequence: 0
184
+ };
185
+ }
186
+ exports.createDefaultTowerState = createDefaultTowerState;
187
+ //# sourceMappingURL=udtHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"udtHelpers.js","sourceRoot":"","sources":["../../src/udtHelpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import type { TowerState } from './udtTowerState';
2
+ export type LogLevel = 'all' | 'debug' | 'info' | 'warn' | 'error';
3
+ export interface LogOutput {
4
+ write(level: LogLevel, message: string, timestamp: Date): void;
5
+ }
6
+ export declare class ConsoleOutput implements LogOutput {
7
+ write(level: LogLevel, message: string): void;
8
+ }
9
+ export interface LogEntry {
10
+ level: LogLevel;
11
+ message: string;
12
+ timestamp: Date;
13
+ }
14
+ export declare class BufferOutput implements LogOutput {
15
+ private buffer;
16
+ private maxEntries;
17
+ private clearCount;
18
+ constructor(maxEntries?: number, clearCount?: number);
19
+ write(level: LogLevel, message: string, timestamp: Date): void;
20
+ getBuffer(): LogEntry[];
21
+ getBufferSize(): number;
22
+ clearBuffer(): void;
23
+ getEntriesByLevel(level: LogLevel): LogEntry[];
24
+ getEntriesSince(timestamp: Date): LogEntry[];
25
+ }
26
+ export declare class DOMOutput implements LogOutput {
27
+ private container;
28
+ private maxLines;
29
+ private allEntries;
30
+ constructor(containerId: string, maxLines?: number);
31
+ write(level: LogLevel, message: string, timestamp: Date): void;
32
+ private refreshDisplay;
33
+ private getEnabledLevelsFromCheckboxes;
34
+ private getTextFilter;
35
+ private updateBufferSizeDisplay;
36
+ refreshFilter(): void;
37
+ clearAll(): void;
38
+ getEntryCount(): number;
39
+ getEnabledLevels(): string[];
40
+ debugEntries(): void;
41
+ }
42
+ export declare class Logger {
43
+ private outputs;
44
+ private enabledLevels;
45
+ private static instance;
46
+ constructor();
47
+ static getInstance(): Logger;
48
+ addOutput(output: LogOutput): void;
49
+ setMinLevel(level: LogLevel): void;
50
+ setEnabledLevels(levels: LogLevel[]): void;
51
+ enableLevel(level: LogLevel): void;
52
+ disableLevel(level: LogLevel): void;
53
+ getEnabledLevels(): LogLevel[];
54
+ private shouldLog;
55
+ private log;
56
+ debug(message: string, context?: string): void;
57
+ info(message: string, context?: string): void;
58
+ warn(message: string, context?: string): void;
59
+ error(message: string, context?: string): void;
60
+ /**
61
+ * Logs tower state changes with detailed information about what changed.
62
+ * @param oldState - The previous tower state
63
+ * @param newState - The new tower state
64
+ * @param source - Source identifier for the update (e.g., "sendTowerState", "tower response")
65
+ * @param enableDetailedLogging - Whether to include detailed change descriptions
66
+ */
67
+ logTowerStateChange(oldState: TowerState, newState: TowerState, source: string, enableDetailedLogging?: boolean): void;
68
+ /**
69
+ * Computes the differences between two tower states for logging purposes.
70
+ * @param oldState - The previous tower state
71
+ * @param newState - The new tower state
72
+ * @returns Array of human-readable change descriptions
73
+ */
74
+ private computeStateChanges;
75
+ }
76
+ export declare const logger: Logger;