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.
- package/LICENSE +21 -0
- package/README.md +138 -0
- package/dist/src/UltimateDarkTower.d.ts +379 -0
- package/dist/src/UltimateDarkTower.js +728 -0
- package/dist/src/UltimateDarkTower.js.map +1 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.js +40 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/udtBleConnection.d.ts +96 -0
- package/dist/src/udtBleConnection.js +412 -0
- package/dist/src/udtBleConnection.js.map +1 -0
- package/dist/src/udtCommandFactory.d.ts +98 -0
- package/dist/src/udtCommandFactory.js +263 -0
- package/dist/src/udtCommandFactory.js.map +1 -0
- package/dist/src/udtCommandQueue.d.ts +51 -0
- package/dist/src/udtCommandQueue.js +143 -0
- package/dist/src/udtCommandQueue.js.map +1 -0
- package/dist/src/udtConstants.d.ts +278 -0
- package/dist/src/udtConstants.js +315 -0
- package/dist/src/udtConstants.js.map +1 -0
- package/dist/src/udtHelpers.d.ts +82 -0
- package/dist/src/udtHelpers.js +187 -0
- package/dist/src/udtHelpers.js.map +1 -0
- package/dist/src/udtLogger.d.ts +76 -0
- package/dist/src/udtLogger.js +344 -0
- package/dist/src/udtLogger.js.map +1 -0
- package/dist/src/udtTowerCommands.d.ts +210 -0
- package/dist/src/udtTowerCommands.js +620 -0
- package/dist/src/udtTowerCommands.js.map +1 -0
- package/dist/src/udtTowerResponse.d.ts +43 -0
- package/dist/src/udtTowerResponse.js +98 -0
- package/dist/src/udtTowerResponse.js.map +1 -0
- package/dist/src/udtTowerState.d.ts +59 -0
- package/dist/src/udtTowerState.js +198 -0
- package/dist/src/udtTowerState.js.map +1 -0
- 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;
|