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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Chris Zeller (Koerner)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,138 @@
1
+ # UltimateDarkTower
2
+
3
+ A JavaScript/TypeScript library for controlling the Bluetooth-enabled tower from Restoration Games' Return to Dark Tower board game. Control lights, sounds, drum rotation, and track game state through Web Bluetooth.
4
+
5
+ I have spent many hours reverse engineering the Tower's protocol in order to create this library, I look forward to what others will create using this! - Chris
6
+
7
+ ## Table of Contents
8
+
9
+ - [UltimateDarkTower](#ultimatedarktower)
10
+ - [Table of Contents](#table-of-contents)
11
+ - [Features](#features)
12
+ - [Live Examples](#live-examples)
13
+ - [Installation](#installation)
14
+ - [Documentation](#documentation)
15
+ - [📖 Complete API Reference](#-complete-api-reference)
16
+ - [Key Topics Covered:](#key-topics-covered)
17
+ - [Development](#development)
18
+ - [Building and Testing](#building-and-testing)
19
+ - [Project Structure](#project-structure)
20
+ - [Browser Support](#browser-support)
21
+ - [Known Issues](#known-issues)
22
+ - [Community](#community)
23
+
24
+ ## Features
25
+
26
+ - **Bluetooth Connection Management** - Reliable connection with automatic monitoring and disconnect detection
27
+ - **Tower Control** - Complete control over lights, sounds, and drum rotation
28
+ - **Game State Tracking** - Track glyph positions, broken seals, and skull counts
29
+ - **Event System** - Callback-based event handling for tower events
30
+ - **TypeScript Support** - Full TypeScript definitions and type safety
31
+ - **Comprehensive Logging** - Multi-output logging system for debugging
32
+ - **Battery Monitoring** - Real-time battery level tracking and low battery warnings
33
+
34
+ ## Live Examples
35
+
36
+ Try the library in action! Just power on your Tower and visit:
37
+
38
+ - **[Tower Controller](https://chessmess.github.io/UltimateDarkTower/dist/examples/controller/TowerController.html)** - Replicates official app functionality and gives examples of library functionality.
39
+
40
+ - **[Tower Game](https://chessmess.github.io/UltimateDarkTower/dist/examples/game/TowerGame.html)** - "The Tower's Challenge" - a complete game using just the tower
41
+
42
+ _Requires Web Bluetooth support (Chrome, Edge, Samsung Internet). For iOS, use the [Bluefy app](https://apps.apple.com/us/app/bluefy-web-ble-browser/id1492822055)._
43
+
44
+ ## Installation
45
+
46
+ ```bash
47
+ npm install ultimatedarktower
48
+ ```
49
+
50
+ ## Documentation
51
+
52
+ ### 📖 [Complete API Reference](Reference.md)
53
+
54
+ Comprehensive documentation with TypeScript examples, best practices, and troubleshooting guides.
55
+
56
+ ### Key Topics Covered:
57
+
58
+ - **Connection Management** - Connecting, disconnecting, and monitoring connection health
59
+ - **Tower Control** - Detailed coverage of all tower commands (lights, sounds, rotation)
60
+ - **Glyph System** - Automatic tracking of glyph positions as towers rotate
61
+ - **Seal Management** - Breaking seals and tracking game state
62
+ - **Event Handling** - Callback system for tower events
63
+ - **Logging System** - Multi-output logging for debugging and monitoring
64
+ - **Best Practices** - Performance tips, error handling, and common patterns
65
+ - **Troubleshooting** - Solutions for common issues and debugging techniques
66
+
67
+ ## Development
68
+
69
+ ### Building and Testing
70
+
71
+ ```bash
72
+ # Install dependencies
73
+ npm install
74
+
75
+ # Build the project
76
+ npm run build
77
+
78
+ # Run tests
79
+ npm test
80
+
81
+ # Run tests with coverage
82
+ npm run test:coverage
83
+
84
+ # Lint code
85
+ npm run lint
86
+
87
+ # Watch mode for development
88
+ npm run watch
89
+ ```
90
+
91
+ ### Project Structure
92
+
93
+ ```
94
+ src/
95
+ ├── index.ts # Main exports
96
+ ├── UltimateDarkTower.ts # Main class
97
+ ├── udtBleConnection.ts # Bluetooth connection management
98
+ ├── udtTowerCommands.ts # Tower command implementations
99
+ ├── udtCommandFactory.ts # Command creation utilities
100
+ ├── udtCommandQueue.ts # Command queue management
101
+ ├── udtTowerResponse.ts # Response handling
102
+ ├── udtTowerState.ts # Tower state management
103
+ ├── udtHelpers.ts # Utility helper functions
104
+ ├── udtLogger.ts # Logging system
105
+ └── udtConstants.ts # Constants and type definitions
106
+
107
+ examples/
108
+ ├── controller/ # Tower controller web app
109
+ ├── game/ # Tower game web app
110
+ └── assets/ # Shared assets (images, fonts, etc.)
111
+ ```
112
+
113
+ ## Browser Support
114
+
115
+ Web Bluetooth is required for this library to function.
116
+
117
+ **✅ Supported Browsers:**
118
+
119
+ - Chrome (desktop and Android)
120
+ - Microsoft Edge
121
+ - Samsung Internet
122
+
123
+ **📱 iOS Support:** Use the [Bluefy app](https://apps.apple.com/us/app/bluefy-web-ble-browser/id1492822055) when on iPhone or iPads as Chrome/Safari does not have Web Bluetooth support on Apples platform at the moment.
124
+
125
+ **❌ Not Supported:** Firefox, Safari ([compatibility details](https://caniuse.com/?search=web%20bluetooth))
126
+
127
+ ## Known Issues
128
+
129
+ This library is in **Release Candidate** status. Current limitations:
130
+
131
+ - **Tower Response Handling** - Not all tower responses are fully processed
132
+ common game patterns are planned
133
+
134
+ > See [Reference.md](Reference.md) for performance best practices and workarounds.
135
+
136
+ ## Community
137
+
138
+ Questions? Ideas? Join us on our [Discord Server](https://discord.com/channels/722465956265197618/1167555008376610945/1167842435766952158)!
@@ -0,0 +1,379 @@
1
+ import { type Lights, type TowerSide, type SealIdentifier, type Glyphs } from './udtConstants';
2
+ import { type TowerState } from './udtTowerState';
3
+ import { type LogOutput } from './udtLogger';
4
+ import { type ConnectionStatus } from './udtBleConnection';
5
+ /**
6
+ * Configuration interface for controlling which tower responses should be logged
7
+ */
8
+ interface TowerResponseConfig {
9
+ TOWER_STATE: boolean;
10
+ INVALID_STATE: boolean;
11
+ HARDWARE_FAILURE: boolean;
12
+ MECH_JIGGLE_TRIGGERED: boolean;
13
+ MECH_UNEXPECTED_TRIGGER: boolean;
14
+ MECH_DURATION: boolean;
15
+ DIFFERENTIAL_READINGS: boolean;
16
+ BATTERY_READING: boolean;
17
+ CALIBRATION_FINISHED: boolean;
18
+ LOG_ALL: boolean;
19
+ }
20
+ /**
21
+ * @title UltimateDarkTower
22
+ * @description
23
+ * The UltimateDarkTower class is the main control interface for the Return To Dark Tower board game device.
24
+ * It provides a comprehensive API for interacting with the tower through Bluetooth Low Energy (BLE).
25
+ *
26
+ * Usage:
27
+ * 1. Create instance: const tower = new UltimateDarkTower()
28
+ * 2. Connect to tower: await tower.connect()
29
+ * 3. Calibrate tower: await tower.calibrate()
30
+ * 4. Use tower commands: await tower.playSound(1), await tower.Lights({...}), etc.
31
+ * 5. Clean up: await tower.cleanup()
32
+ *
33
+ * Event Callbacks:
34
+ * - onTowerConnect: Called when tower connects
35
+ * - onTowerDisconnect: Called when tower disconnects
36
+ * - onCalibrationComplete: Called when calibration finishes
37
+ * - onSkullDrop: Called when skulls are dropped into the tower
38
+ * - onBatteryLevelNotify: Called when battery level updates
39
+ * - onTowerStateUpdate: Called whenever the tower state is updated
40
+ */
41
+ declare class UltimateDarkTower {
42
+ private logger;
43
+ private bleConnection;
44
+ private towerEventCallbacks;
45
+ private responseProcessor;
46
+ private commandFactory;
47
+ private towerCommands;
48
+ private retrySendCommandCountRef;
49
+ retrySendCommandMax: number;
50
+ currentBatteryValue: number;
51
+ previousBatteryValue: number;
52
+ currentBatteryPercentage: number;
53
+ previousBatteryPercentage: number;
54
+ private brokenSeals;
55
+ private currentTowerState;
56
+ private glyphPositions;
57
+ onTowerConnect: () => void;
58
+ onTowerDisconnect: () => void;
59
+ onCalibrationComplete: () => void;
60
+ onSkullDrop: (towerSkullCount: number) => void;
61
+ onBatteryLevelNotify: (millivolts: number) => void;
62
+ onTowerStateUpdate: (newState: TowerState, oldState: TowerState, source: string) => void;
63
+ constructor();
64
+ /**
65
+ * Initialize the logger with default console output
66
+ */
67
+ private initializeLogger;
68
+ /**
69
+ * Initialize all tower components and their dependencies
70
+ */
71
+ private initializeComponents;
72
+ /**
73
+ * Set up the tower response callback after all components are initialized
74
+ */
75
+ private setupTowerResponseCallback; /**
76
+ * Create tower event callbacks for BLE connection
77
+ */
78
+ private createTowerEventCallbacks;
79
+ /**
80
+ * Create command dependencies object for tower commands
81
+ */
82
+ private createCommandDependencies;
83
+ /**
84
+ * Update battery state values
85
+ */
86
+ private updateBatteryState;
87
+ private _logDetail;
88
+ get logDetail(): boolean;
89
+ set logDetail(value: boolean);
90
+ /**
91
+ * Update tower command dependencies when configuration changes
92
+ */
93
+ private updateTowerCommandDependencies;
94
+ get isConnected(): boolean;
95
+ get isCalibrated(): boolean;
96
+ get performingCalibration(): boolean;
97
+ get performingLongCommand(): boolean;
98
+ get towerSkullDropCount(): number;
99
+ get txCharacteristic(): any;
100
+ get currentBattery(): number;
101
+ get previousBattery(): number;
102
+ get currentBatteryPercent(): number;
103
+ get previousBatteryPercent(): number;
104
+ get batteryNotifyFrequency(): number;
105
+ set batteryNotifyFrequency(value: number);
106
+ get batteryNotifyOnValueChangeOnly(): boolean;
107
+ set batteryNotifyOnValueChangeOnly(value: boolean);
108
+ get batteryNotifyEnabled(): boolean;
109
+ set batteryNotifyEnabled(value: boolean);
110
+ get logTowerResponses(): boolean;
111
+ set logTowerResponses(value: boolean);
112
+ get logTowerResponseConfig(): TowerResponseConfig;
113
+ set logTowerResponseConfig(value: TowerResponseConfig);
114
+ /**
115
+ * Initiates tower calibration to determine the current position of all tower drums.
116
+ * This must be performed after connection before other tower operations.
117
+ * @returns Promise that resolves when calibration command is sent
118
+ */
119
+ calibrate(): Promise<void>;
120
+ /**
121
+ * Plays a sound from the tower's audio library.
122
+ * @param soundIndex - Index of the sound to play (1-based, must be valid in TOWER_AUDIO_LIBRARY)
123
+ * @returns Promise that resolves when sound command is sent
124
+ */
125
+ playSound(soundIndex: number): Promise<void>;
126
+ /**
127
+ * Controls the tower's LED lights including doorway, ledge, and base lights.
128
+ * @param lights - Light configuration object specifying which lights to control and their effects
129
+ * @returns Promise that resolves when light command is sent
130
+ */
131
+ lights(lights: Lights): Promise<void>;
132
+ /**
133
+ * Controls the tower's LED lights including doorway, ledge, and base lights.
134
+ * @deprecated Use `lights()` instead. This method will be removed in a future version.
135
+ * @param lights - Light configuration object specifying which lights to control and their effects
136
+ * @returns Promise that resolves when light command is sent
137
+ */
138
+ Lights(lights: Lights): Promise<void>;
139
+ /**
140
+ * Sends a raw command packet directly to the tower (for testing purposes).
141
+ * @param command - The raw command packet to send
142
+ * @returns Promise that resolves when command is sent
143
+ */
144
+ sendTowerCommandDirect(command: Uint8Array): Promise<void>;
145
+ /**
146
+ * Sends a light override command to control specific light patterns.
147
+ * @param light - Light override value to send
148
+ * @param soundIndex - Optional sound to play with the light override
149
+ * @returns Promise that resolves when light override command is sent
150
+ */
151
+ lightOverrides(light: number, soundIndex?: number): Promise<void>;
152
+ /**
153
+ * Rotates tower drums to specified positions.
154
+ * @param top - Position for the top drum ('north', 'east', 'south', 'west')
155
+ * @param middle - Position for the middle drum
156
+ * @param bottom - Position for the bottom drum
157
+ * @param soundIndex - Optional sound to play during rotation
158
+ * @returns Promise that resolves when rotate command is sent
159
+ */
160
+ Rotate(top: TowerSide, middle: TowerSide, bottom: TowerSide, soundIndex?: number): Promise<void>;
161
+ /**
162
+ * Resets the tower's internal skull drop counter to zero.
163
+ * @returns Promise that resolves when reset command is sent
164
+ */
165
+ resetTowerSkullCount(): Promise<void>;
166
+ /**
167
+ * Sets a specific LED using stateful commands that preserve all other tower state.
168
+ * This is the recommended way to control individual LEDs.
169
+ * @param layerIndex - Layer index (0-5: TopRing, MiddleRing, BottomRing, Ledge, Base1, Base2)
170
+ * @param lightIndex - Light index within layer (0-3)
171
+ * @param effect - Light effect (0=off, 1=on, 2=slow pulse, 3=fast pulse, etc.)
172
+ * @param loop - Whether to loop the effect
173
+ * @returns Promise that resolves when command is sent
174
+ */
175
+ setLED(layerIndex: number, lightIndex: number, effect: number, loop?: boolean): Promise<void>;
176
+ /**
177
+ * Plays a sound using stateful commands that preserve existing tower state.
178
+ * @param soundIndex - Index of the sound to play (1-based)
179
+ * @param loop - Whether to loop the audio
180
+ * @param volume - Audio volume (0-15), optional
181
+ * @returns Promise that resolves when command is sent
182
+ */
183
+ playSoundStateful(soundIndex: number, loop?: boolean, volume?: number): Promise<void>;
184
+ /**
185
+ * Rotates a single drum using stateful commands that preserve existing tower state.
186
+ * @param drumIndex - Drum index (0=top, 1=middle, 2=bottom)
187
+ * @param position - Target position (0=north, 1=east, 2=south, 3=west)
188
+ * @param playSound - Whether to play sound during rotation
189
+ * @returns Promise that resolves when command is sent
190
+ */
191
+ rotateDrumStateful(drumIndex: number, position: number, playSound?: boolean): Promise<void>;
192
+ /**
193
+ * Rotates tower drums to specified positions using stateful commands that preserve existing tower state.
194
+ * This is the recommended way to rotate drums as it preserves LEDs and other tower state.
195
+ * @param top - Position for the top drum ('north', 'east', 'south', 'west')
196
+ * @param middle - Position for the middle drum
197
+ * @param bottom - Position for the bottom drum
198
+ * @param soundIndex - Optional sound to play during rotation
199
+ * @returns Promise that resolves when rotate command is sent
200
+ */
201
+ rotateWithState(top: TowerSide, middle: TowerSide, bottom: TowerSide, soundIndex?: number): Promise<void>;
202
+ /**
203
+ * Gets the current complete tower state if available.
204
+ * @returns The current tower state object
205
+ */
206
+ getCurrentTowerState(): TowerState;
207
+ /**
208
+ * Sends a complete tower state to the tower, preserving existing state.
209
+ * Audio state is automatically cleared to prevent sounds from persisting across commands.
210
+ * @param towerState - The tower state to send
211
+ * @returns Promise that resolves when the command is sent
212
+ */
213
+ sendTowerState(towerState: TowerState): Promise<void>;
214
+ /**
215
+ * Sets the tower state with comprehensive logging of changes.
216
+ * @param newState - The new tower state to set
217
+ * @param source - Source identifier for logging (e.g., "sendTowerState", "tower response")
218
+ */
219
+ private setTowerState;
220
+ /**
221
+ * Updates the current tower state from a tower response.
222
+ * Called internally when tower state responses are received.
223
+ * Audio state is reset to prevent sounds from persisting across commands.
224
+ * @param stateData - The 19-byte state data from tower response
225
+ */
226
+ private updateTowerStateFromResponse;
227
+ /**
228
+ * Breaks a single seal on the tower, playing appropriate sound and lighting effects.
229
+ * @param seal - Seal identifier to break (e.g., {side: 'north', level: 'middle'})
230
+ * @param volume - Optional volume override (0=loud, 1=medium, 2=quiet, 3=mute). Uses current tower state if not provided.
231
+ * @returns Promise that resolves when seal break sequence is complete
232
+ */
233
+ breakSeal(seal: SealIdentifier, volume?: number): Promise<void>;
234
+ /**
235
+ * Randomly rotates specified tower levels to random positions.
236
+ * @param level - Level configuration: 0=all, 1=top, 2=middle, 3=bottom, 4=top&middle, 5=top&bottom, 6=middle&bottom
237
+ * @returns Promise that resolves when rotation command is sent
238
+ */
239
+ randomRotateLevels(level?: number): Promise<void>;
240
+ /**
241
+ * Gets the current position of a specific drum level.
242
+ * @param level - The drum level to get position for
243
+ * @returns The current position of the specified drum level
244
+ */
245
+ getCurrentDrumPosition(level: 'top' | 'middle' | 'bottom'): TowerSide;
246
+ /**
247
+ * Sets the initial glyph positions from calibration.
248
+ * Called automatically when calibration completes.
249
+ */
250
+ private setGlyphPositionsFromCalibration;
251
+ /**
252
+ * Gets the current position of a specific glyph.
253
+ * @param glyph - The glyph to get position for
254
+ * @returns The current position of the glyph, or null if not calibrated
255
+ */
256
+ getGlyphPosition(glyph: Glyphs): TowerSide | null;
257
+ /**
258
+ * Gets all current glyph positions.
259
+ * @returns Object mapping each glyph to its current position (or null if not calibrated)
260
+ */
261
+ getAllGlyphPositions(): {
262
+ [key in Glyphs]: TowerSide | null;
263
+ };
264
+ /**
265
+ * Gets all glyphs currently facing a specific direction.
266
+ * @param direction - The direction to check for (north, east, south, west)
267
+ * @returns Array of glyph names that are currently facing the specified direction
268
+ */
269
+ getGlyphsFacingDirection(direction: TowerSide): Glyphs[];
270
+ /**
271
+ * Updates glyph positions after a drum rotation.
272
+ * @param level - The drum level that was rotated
273
+ * @param rotationSteps - Number of steps rotated (1 = 90 degrees clockwise)
274
+ */
275
+ private updateGlyphPositionsAfterRotation;
276
+ /**
277
+ * Calculates rotation steps and updates glyph positions for a specific level.
278
+ * @param level - The drum level that was rotated
279
+ * @param oldPosition - The position before rotation
280
+ * @param newPosition - The position after rotation
281
+ */
282
+ private calculateAndUpdateGlyphPositions;
283
+ /**
284
+ * Updates glyph positions for a specific level rotation.
285
+ * @param level - The drum level that was rotated
286
+ * @param newPosition - The new position the drum was rotated to
287
+ * @deprecated Use calculateAndUpdateGlyphPositions instead
288
+ */
289
+ private updateGlyphPositionsForRotation;
290
+ /**
291
+ * Checks if a specific seal is broken.
292
+ * @param seal - The seal identifier to check
293
+ * @returns True if the seal is broken, false otherwise
294
+ */
295
+ isSealBroken(seal: SealIdentifier): boolean;
296
+ /**
297
+ * Gets a list of all broken seals.
298
+ * @returns Array of SealIdentifier objects representing all broken seals
299
+ */
300
+ getBrokenSeals(): SealIdentifier[];
301
+ /**
302
+ * Resets the broken seals tracking (clears all broken seals).
303
+ */
304
+ resetBrokenSeals(): void;
305
+ /**
306
+ * Gets a random unbroken seal that can be passed to breakSeal().
307
+ * @returns A random SealIdentifier that is not currently broken, or null if all seals are broken
308
+ */
309
+ getRandomUnbrokenSeal(): SealIdentifier | null;
310
+ /**
311
+ * Establishes a Bluetooth connection to the Dark Tower device.
312
+ * Initializes GATT services, characteristics, and starts connection monitoring.
313
+ * @returns {Promise<void>} Promise that resolves when connection is established
314
+ */
315
+ connect(): Promise<void>;
316
+ /**
317
+ * Disconnects from the tower device and cleans up resources.
318
+ * @returns {Promise<void>} Promise that resolves when disconnection is complete
319
+ */
320
+ disconnect(): Promise<void>;
321
+ /**
322
+ * Configure logger outputs for this UltimateDarkTower instance
323
+ * @param {LogOutput[]} outputs - Array of log outputs to use (e.g., ConsoleOutput, DOMOutput)
324
+ */
325
+ setLoggerOutputs(outputs: LogOutput[]): void;
326
+ /**
327
+ * Sends a command packet to the tower via Bluetooth with error handling and retry logic.
328
+ * @param {Uint8Array} command - The command packet to send to the tower
329
+ * @returns {Promise<void>} Promise that resolves when command is sent successfully
330
+ */
331
+ sendTowerCommand(command: Uint8Array): Promise<void>;
332
+ /**
333
+ * Converts a command packet to a hex string representation for debugging.
334
+ * @param {Uint8Array} command - Command packet to convert
335
+ * @returns {string} Hex string representation of the command packet
336
+ */
337
+ commandToPacketString(command: Uint8Array): string;
338
+ /**
339
+ * Converts battery voltage in millivolts to percentage.
340
+ * @param {number} mv - Battery voltage in millivolts
341
+ * @returns {string} Battery percentage as formatted string (e.g., "75%")
342
+ */
343
+ milliVoltsToPercentage(mv: number): string;
344
+ /**
345
+ * Enable or disable connection monitoring
346
+ * @param {boolean} enabled - Whether to enable connection monitoring
347
+ */
348
+ setConnectionMonitoring(enabled: boolean): void;
349
+ /**
350
+ * Configure connection monitoring parameters
351
+ * @param {number} [frequency=2000] - How often to check connection (milliseconds)
352
+ * @param {number} [timeout=30000] - How long to wait for responses before considering connection lost (milliseconds)
353
+ */
354
+ configureConnectionMonitoring(frequency?: number, timeout?: number): void;
355
+ /**
356
+ * Configure battery heartbeat monitoring parameters
357
+ * Tower sends battery status every ~200ms, so this is the most reliable disconnect indicator
358
+ * @param {boolean} [enabled=true] - Whether to enable battery heartbeat monitoring
359
+ * @param {number} [timeout=3000] - How long to wait for battery status before considering disconnected (milliseconds)
360
+ * @param {boolean} [verifyConnection=true] - Whether to verify connection status before triggering disconnection on heartbeat timeout
361
+ */
362
+ configureBatteryHeartbeatMonitoring(enabled?: boolean, timeout?: number, verifyConnection?: boolean): void;
363
+ /**
364
+ * Check if the tower is currently connected
365
+ * @returns {Promise<boolean>} True if connected and responsive
366
+ */
367
+ isConnectedAndResponsive(): Promise<boolean>;
368
+ /**
369
+ * Get detailed connection status including heartbeat information
370
+ * @returns {Object} Object with connection details
371
+ */
372
+ getConnectionStatus(): ConnectionStatus;
373
+ /**
374
+ * Clean up resources and disconnect properly
375
+ * @returns {Promise<void>} Promise that resolves when cleanup is complete
376
+ */
377
+ cleanup(): Promise<void>;
378
+ }
379
+ export default UltimateDarkTower;