@opendisplay/opendisplay 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.
@@ -0,0 +1,780 @@
1
+ import { ColorScheme, DitherMode } from '@opendisplay/epaper-dithering';
2
+ export { ColorScheme, DitherMode } from '@opendisplay/epaper-dithering';
3
+
4
+ /**
5
+ * Device capabilities model.
6
+ */
7
+
8
+ /**
9
+ * Minimal device information needed for image upload.
10
+ */
11
+ interface DeviceCapabilities {
12
+ /** Display width in pixels */
13
+ width: number;
14
+ /** Display height in pixels */
15
+ height: number;
16
+ /** Display color scheme */
17
+ colorScheme: ColorScheme;
18
+ /** Display rotation in degrees (0, 90, 180, 270) */
19
+ rotation?: number;
20
+ }
21
+
22
+ /**
23
+ * Enums for OpenDisplay device configuration.
24
+ */
25
+ /**
26
+ * Display refresh modes.
27
+ */
28
+ declare enum RefreshMode {
29
+ FULL = 0,
30
+ FAST = 1,
31
+ PARTIAL = 2,
32
+ PARTIAL2 = 3
33
+ }
34
+ /**
35
+ * Microcontroller IC types.
36
+ */
37
+ declare enum ICType {
38
+ NRF52840 = 1,
39
+ ESP32_S3 = 2,
40
+ ESP32_C3 = 3,
41
+ ESP32_C6 = 4
42
+ }
43
+ /**
44
+ * Power source types.
45
+ */
46
+ declare enum PowerMode {
47
+ BATTERY = 1,
48
+ USB = 2,
49
+ SOLAR = 3
50
+ }
51
+ /**
52
+ * Data bus types for sensors.
53
+ */
54
+ declare enum BusType {
55
+ I2C = 0,
56
+ SPI = 1
57
+ }
58
+ /**
59
+ * Display rotation angles in degrees.
60
+ */
61
+ declare enum Rotation {
62
+ ROTATE_0 = 0,
63
+ ROTATE_90 = 90,
64
+ ROTATE_180 = 180,
65
+ ROTATE_270 = 270
66
+ }
67
+
68
+ /**
69
+ * TLV configuration data structures.
70
+ *
71
+ * These interfaces map directly to the firmware's TLV packet structures.
72
+ * Reference: OpenDisplayFirmware/src/structs.h
73
+ */
74
+
75
+ /**
76
+ * System configuration (TLV packet type 0x01).
77
+ *
78
+ * Size: 22 bytes (packed struct from firmware)
79
+ */
80
+ interface SystemConfig {
81
+ /** uint16 - IC type identifier */
82
+ icType: number;
83
+ /** uint8 bitfield - Supported communication modes */
84
+ communicationModes: number;
85
+ /** uint8 bitfield - Device capability flags */
86
+ deviceFlags: number;
87
+ /** uint8 - External power pin (0xFF = none) */
88
+ pwrPin: number;
89
+ /** 17 bytes - Reserved for future use */
90
+ reserved: Uint8Array;
91
+ }
92
+ /**
93
+ * Helper functions for SystemConfig
94
+ */
95
+ declare namespace SystemConfig {
96
+ const SIZE = 22;
97
+ /**
98
+ * Check if device has external power management pin (DEVICE_FLAG_PWR_PIN).
99
+ */
100
+ function hasPwrPin(config: SystemConfig): boolean;
101
+ /**
102
+ * Check if xiaoinit() should be called after config load - nRF52840 only (DEVICE_FLAG_XIAOINIT).
103
+ */
104
+ function needsXiaoinit(config: SystemConfig): boolean;
105
+ /**
106
+ * Get IC type as enum, or raw int if unknown.
107
+ */
108
+ function icTypeEnum(config: SystemConfig): ICType | number;
109
+ /**
110
+ * Parse SystemConfig from TLV packet data.
111
+ */
112
+ function fromBytes(data: Uint8Array): SystemConfig;
113
+ }
114
+ /**
115
+ * Manufacturer data (TLV packet type 0x02).
116
+ *
117
+ * Size: 22 bytes (packed struct from firmware)
118
+ */
119
+ interface ManufacturerData {
120
+ /** uint16 - Manufacturer identifier */
121
+ manufacturerId: number;
122
+ /** uint8 - Board type */
123
+ boardType: number;
124
+ /** uint8 - Board revision */
125
+ boardRevision: number;
126
+ /** 18 bytes - Reserved for future use */
127
+ reserved: Uint8Array;
128
+ }
129
+ /**
130
+ * Helper functions for ManufacturerData
131
+ */
132
+ declare namespace ManufacturerData {
133
+ const SIZE = 22;
134
+ /**
135
+ * Parse ManufacturerData from TLV packet data.
136
+ */
137
+ function fromBytes(data: Uint8Array): ManufacturerData;
138
+ }
139
+ /**
140
+ * Power configuration (TLV packet type 0x04).
141
+ *
142
+ * Size: 30 bytes (packed struct from firmware - corrected from 32)
143
+ */
144
+ interface PowerOption {
145
+ /** uint8 - Power mode identifier */
146
+ powerMode: number;
147
+ /** 3 bytes (24-bit value) - Battery capacity in mAh */
148
+ batteryCapacityMah: number;
149
+ /** uint16 - Sleep timeout in milliseconds */
150
+ sleepTimeoutMs: number;
151
+ /** uint8 - TX power level */
152
+ txPower: number;
153
+ /** uint8 bitfield - Sleep configuration flags */
154
+ sleepFlags: number;
155
+ /** uint8 - Battery sense pin (0xFF = none) */
156
+ batterySensePin: number;
157
+ /** uint8 - Battery sense enable pin (0xFF = none) */
158
+ batterySenseEnablePin: number;
159
+ /** uint8 bitfield - Battery sense flags */
160
+ batterySenseFlags: number;
161
+ /** uint8 - Capacity estimator type */
162
+ capacityEstimator: number;
163
+ /** uint16 - Voltage scaling factor */
164
+ voltageScalingFactor: number;
165
+ /** uint32 - Deep sleep current in microamps */
166
+ deepSleepCurrentUa: number;
167
+ /** uint16 - Deep sleep time in seconds */
168
+ deepSleepTimeSeconds: number;
169
+ /** 10 bytes - Reserved for future use */
170
+ reserved: Uint8Array;
171
+ }
172
+ /**
173
+ * Helper functions for PowerOption
174
+ */
175
+ declare namespace PowerOption {
176
+ const SIZE = 30;
177
+ /**
178
+ * Get battery capacity in mAh (already converted from 3-byte array).
179
+ */
180
+ function batteryMah(config: PowerOption): number;
181
+ /**
182
+ * Get power mode as enum, or raw int if unknown.
183
+ */
184
+ function powerModeEnum(config: PowerOption): PowerMode | number;
185
+ /**
186
+ * Parse PowerOption from TLV packet data.
187
+ */
188
+ function fromBytes(data: Uint8Array): PowerOption;
189
+ }
190
+ /**
191
+ * Display configuration (TLV packet type 0x20, repeatable max 4).
192
+ *
193
+ * Size: 46 bytes (packed struct from firmware - corrected from 66)
194
+ */
195
+ interface DisplayConfig {
196
+ /** uint8 - Display instance number (0-3) */
197
+ instanceNumber: number;
198
+ /** uint8 - Display technology type */
199
+ displayTechnology: number;
200
+ /** uint16 - Panel IC type */
201
+ panelIcType: number;
202
+ /** uint16 - Display width in pixels */
203
+ pixelWidth: number;
204
+ /** uint16 - Display height in pixels */
205
+ pixelHeight: number;
206
+ /** uint16 - Active area width in millimeters */
207
+ activeWidthMm: number;
208
+ /** uint16 - Active area height in millimeters */
209
+ activeHeightMm: number;
210
+ /** uint16 - Tag type (legacy) */
211
+ tagType: number;
212
+ /** uint8 - Display rotation in degrees */
213
+ rotation: number;
214
+ /** uint8 - Reset pin (0xFF = none) */
215
+ resetPin: number;
216
+ /** uint8 - Busy pin (0xFF = none) */
217
+ busyPin: number;
218
+ /** uint8 - Data/Command pin (0xFF = none) */
219
+ dcPin: number;
220
+ /** uint8 - Chip select pin (0xFF = none) */
221
+ csPin: number;
222
+ /** uint8 - Data pin */
223
+ dataPin: number;
224
+ /** uint8 - Partial update support level */
225
+ partialUpdateSupport: number;
226
+ /** uint8 - Color scheme identifier */
227
+ colorScheme: number;
228
+ /** uint8 bitfield - Supported transmission modes */
229
+ transmissionModes: number;
230
+ /** uint8 - Clock pin */
231
+ clkPin: number;
232
+ /** 7 bytes - Reserved pin slots */
233
+ reservedPins: Uint8Array;
234
+ /** 15 bytes - Reserved for future use */
235
+ reserved: Uint8Array;
236
+ }
237
+ /**
238
+ * Helper functions for DisplayConfig
239
+ */
240
+ declare namespace DisplayConfig {
241
+ const SIZE = 46;
242
+ /**
243
+ * Check if display supports raw image transmission (TRANSMISSION_MODE_RAW).
244
+ */
245
+ function supportsRaw(config: DisplayConfig): boolean;
246
+ /**
247
+ * Check if display supports ZIP compressed transmission (TRANSMISSION_MODE_ZIP).
248
+ */
249
+ function supportsZip(config: DisplayConfig): boolean;
250
+ /**
251
+ * Check if display supports Group 5 compression (TRANSMISSION_MODE_G5).
252
+ */
253
+ function supportsG5(config: DisplayConfig): boolean;
254
+ /**
255
+ * Check if display supports direct write mode - bufferless (TRANSMISSION_MODE_DIRECT_WRITE).
256
+ */
257
+ function supportsDirectWrite(config: DisplayConfig): boolean;
258
+ /**
259
+ * Check if display should clear screen at bootup (TRANSMISSION_MODE_CLEAR_ON_BOOT).
260
+ */
261
+ function clearOnBoot(config: DisplayConfig): boolean;
262
+ /**
263
+ * Get color scheme as enum, or raw int if unknown.
264
+ */
265
+ function colorSchemeEnum(config: DisplayConfig): ColorScheme | number;
266
+ /**
267
+ * Get rotation as enum, or raw int if unknown.
268
+ */
269
+ function rotationEnum(config: DisplayConfig): Rotation | number;
270
+ /**
271
+ * Parse DisplayConfig from TLV packet data.
272
+ */
273
+ function fromBytes(data: Uint8Array): DisplayConfig;
274
+ }
275
+ /**
276
+ * LED configuration (TLV packet type 0x21, repeatable max 4).
277
+ *
278
+ * Size: 22 bytes (packed struct from firmware)
279
+ */
280
+ interface LedConfig {
281
+ /** uint8 - LED instance number */
282
+ instanceNumber: number;
283
+ /** uint8 - LED type */
284
+ ledType: number;
285
+ /** uint8 - Red channel pin */
286
+ led1R: number;
287
+ /** uint8 - Green channel pin */
288
+ led2G: number;
289
+ /** uint8 - Blue channel pin */
290
+ led3B: number;
291
+ /** uint8 - 4th channel pin */
292
+ led4: number;
293
+ /** uint8 bitfield - LED configuration flags */
294
+ ledFlags: number;
295
+ /** 15 bytes - Reserved for future use */
296
+ reserved: Uint8Array;
297
+ }
298
+ /**
299
+ * Helper functions for LedConfig
300
+ */
301
+ declare namespace LedConfig {
302
+ const SIZE = 22;
303
+ /**
304
+ * Parse LedConfig from TLV packet data.
305
+ */
306
+ function fromBytes(data: Uint8Array): LedConfig;
307
+ }
308
+ /**
309
+ * Sensor configuration (TLV packet type 0x23, repeatable max 4).
310
+ *
311
+ * Size: 30 bytes (packed struct from firmware)
312
+ */
313
+ interface SensorData {
314
+ /** uint8 - Sensor instance number */
315
+ instanceNumber: number;
316
+ /** uint16 - Sensor type identifier */
317
+ sensorType: number;
318
+ /** uint8 - Data bus ID */
319
+ busId: number;
320
+ /** 26 bytes - Reserved for future use */
321
+ reserved: Uint8Array;
322
+ }
323
+ /**
324
+ * Helper functions for SensorData
325
+ */
326
+ declare namespace SensorData {
327
+ const SIZE = 30;
328
+ /**
329
+ * Parse SensorData from TLV packet data.
330
+ */
331
+ function fromBytes(data: Uint8Array): SensorData;
332
+ }
333
+ /**
334
+ * Data bus configuration (TLV packet type 0x24, repeatable max 4).
335
+ *
336
+ * Size: 30 bytes (packed struct from firmware - corrected from 28)
337
+ */
338
+ interface DataBus {
339
+ /** uint8 - Bus instance number */
340
+ instanceNumber: number;
341
+ /** uint8 - Bus type identifier */
342
+ busType: number;
343
+ /** uint8 - Pin 1 (SCL for I2C) */
344
+ pin1: number;
345
+ /** uint8 - Pin 2 (SDA for I2C) */
346
+ pin2: number;
347
+ /** uint8 - Pin 3 */
348
+ pin3: number;
349
+ /** uint8 - Pin 4 */
350
+ pin4: number;
351
+ /** uint8 - Pin 5 */
352
+ pin5: number;
353
+ /** uint8 - Pin 6 */
354
+ pin6: number;
355
+ /** uint8 - Pin 7 */
356
+ pin7: number;
357
+ /** uint32 - Bus speed in Hz */
358
+ busSpeedHz: number;
359
+ /** uint8 bitfield - Bus configuration flags */
360
+ busFlags: number;
361
+ /** uint8 bitfield - Pullup resistors configuration */
362
+ pullups: number;
363
+ /** uint8 bitfield - Pulldown resistors configuration */
364
+ pulldowns: number;
365
+ /** 14 bytes - Reserved for future use */
366
+ reserved: Uint8Array;
367
+ }
368
+ /**
369
+ * Helper functions for DataBus
370
+ */
371
+ declare namespace DataBus {
372
+ const SIZE = 30;
373
+ /**
374
+ * Get bus type as enum, or raw int if unknown.
375
+ */
376
+ function busTypeEnum(config: DataBus): BusType | number;
377
+ /**
378
+ * Parse DataBus from TLV packet data.
379
+ */
380
+ function fromBytes(data: Uint8Array): DataBus;
381
+ }
382
+ /**
383
+ * Binary inputs configuration (TLV packet type 0x25, repeatable max 4).
384
+ *
385
+ * Size: 30 bytes (packed struct from firmware - corrected from 29)
386
+ */
387
+ interface BinaryInputs {
388
+ /** uint8 - Input instance number */
389
+ instanceNumber: number;
390
+ /** uint8 - Input type */
391
+ inputType: number;
392
+ /** uint8 - Display representation type */
393
+ displayAs: number;
394
+ /** 8 bytes - Reserved pin slots */
395
+ reservedPins: Uint8Array;
396
+ /** uint8 bitfield - Input configuration flags */
397
+ inputFlags: number;
398
+ /** uint8 bitfield - Invert flags */
399
+ invert: number;
400
+ /** uint8 bitfield - Pullup resistors configuration */
401
+ pullups: number;
402
+ /** uint8 bitfield - Pulldown resistors configuration */
403
+ pulldowns: number;
404
+ /** 15 bytes - Reserved for future use */
405
+ reserved: Uint8Array;
406
+ }
407
+ /**
408
+ * Helper functions for BinaryInputs
409
+ */
410
+ declare namespace BinaryInputs {
411
+ const SIZE = 30;
412
+ /**
413
+ * Parse BinaryInputs from TLV packet data.
414
+ */
415
+ function fromBytes(data: Uint8Array): BinaryInputs;
416
+ }
417
+ /**
418
+ * Complete device configuration parsed from TLV data.
419
+ *
420
+ * Corresponds to GlobalConfig struct in firmware.
421
+ */
422
+ interface GlobalConfig {
423
+ /** System configuration (single instance) */
424
+ system?: SystemConfig;
425
+ /** Manufacturer data (single instance) */
426
+ manufacturer?: ManufacturerData;
427
+ /** Power configuration (single instance) */
428
+ power?: PowerOption;
429
+ /** Display configurations (max 4) */
430
+ displays: DisplayConfig[];
431
+ /** LED configurations (max 4) */
432
+ leds: LedConfig[];
433
+ /** Sensor configurations (max 4) */
434
+ sensors: SensorData[];
435
+ /** Data bus configurations (max 4) */
436
+ dataBuses: DataBus[];
437
+ /** Binary input configurations (max 4) */
438
+ binaryInputs: BinaryInputs[];
439
+ /** Configuration version from device */
440
+ version: number;
441
+ /** Minor version (not stored in device) */
442
+ minorVersion: number;
443
+ /** Whether config was successfully loaded */
444
+ loaded: boolean;
445
+ }
446
+
447
+ /**
448
+ * Firmware version data structure.
449
+ */
450
+ interface FirmwareVersion {
451
+ /**
452
+ * Major version number (0-255)
453
+ */
454
+ major: number;
455
+ /**
456
+ * Minor version number (0-255)
457
+ */
458
+ minor: number;
459
+ /**
460
+ * Git commit SHA hash
461
+ */
462
+ sha: string;
463
+ }
464
+
465
+ /**
466
+ * Web Bluetooth connection wrapper for OpenDisplay devices.
467
+ *
468
+ * Provides a clean interface for BLE operations:
469
+ * - Device discovery and connection
470
+ * - Command transmission
471
+ * - Response reception with queuing
472
+ * - Automatic reconnection handling
473
+ */
474
+ /**
475
+ * Connection options for BLE device.
476
+ */
477
+ interface BLEConnectionOptions {
478
+ /**
479
+ * Name prefix to filter devices (e.g., "OpenDisplay")
480
+ * If not provided, user will see all devices with the OpenDisplay service
481
+ */
482
+ namePrefix?: string;
483
+ /**
484
+ * Optional BluetoothDevice to connect to directly
485
+ */
486
+ device?: BluetoothDevice;
487
+ }
488
+
489
+ /**
490
+ * Main OpenDisplay BLE device class.
491
+ */
492
+
493
+ /**
494
+ * OpenDisplay BLE e-paper device.
495
+ *
496
+ * Main API for communicating with OpenDisplay BLE tags.
497
+ *
498
+ * @example
499
+ * ```typescript
500
+ * // Auto-interrogate on first connect
501
+ * const device = new OpenDisplayDevice();
502
+ * await device.connect();
503
+ * await device.uploadImage(imageData);
504
+ * await device.disconnect();
505
+ *
506
+ * // Skip interrogation with cached config
507
+ * const device = new OpenDisplayDevice({ config: cachedConfig });
508
+ * await device.connect();
509
+ *
510
+ * // Skip interrogation with minimal capabilities
511
+ * const caps: DeviceCapabilities = { width: 296, height: 128, colorScheme: ColorScheme.BWR };
512
+ * const device = new OpenDisplayDevice({ capabilities: caps });
513
+ * ```
514
+ */
515
+ declare class OpenDisplayDevice {
516
+ private options;
517
+ static readonly TIMEOUT_FIRST_CHUNK = 10000;
518
+ static readonly TIMEOUT_CHUNK = 2000;
519
+ static readonly TIMEOUT_ACK = 5000;
520
+ static readonly TIMEOUT_REFRESH = 90000;
521
+ private connection;
522
+ private _config;
523
+ private _capabilities;
524
+ private _fwVersion;
525
+ /**
526
+ * Initialize OpenDisplay device.
527
+ *
528
+ * @param options - Device initialization options
529
+ */
530
+ constructor(options?: {
531
+ config?: GlobalConfig;
532
+ capabilities?: DeviceCapabilities;
533
+ device?: BluetoothDevice;
534
+ namePrefix?: string;
535
+ });
536
+ /**
537
+ * Get full device configuration (if interrogated).
538
+ */
539
+ get config(): GlobalConfig | null;
540
+ /**
541
+ * Get device capabilities (width, height, color scheme, rotation).
542
+ */
543
+ get capabilities(): DeviceCapabilities | null;
544
+ /**
545
+ * Get display width in pixels.
546
+ */
547
+ get width(): number;
548
+ /**
549
+ * Get display height in pixels.
550
+ */
551
+ get height(): number;
552
+ /**
553
+ * Get display color scheme.
554
+ */
555
+ get colorScheme(): ColorScheme;
556
+ /**
557
+ * Get display rotation in degrees.
558
+ */
559
+ get rotation(): number;
560
+ /**
561
+ * Check if currently connected to a device.
562
+ */
563
+ get isConnected(): boolean;
564
+ /**
565
+ * Connect to an OpenDisplay device and optionally interrogate.
566
+ *
567
+ * @param connectionOptions - Optional connection parameters
568
+ * @throws {BLEConnectionError} If connection fails
569
+ */
570
+ connect(connectionOptions?: BLEConnectionOptions): Promise<void>;
571
+ /**
572
+ * Disconnect from the device.
573
+ */
574
+ disconnect(): Promise<void>;
575
+ /**
576
+ * Read device configuration from device.
577
+ *
578
+ * @returns GlobalConfig with complete device configuration
579
+ * @throws {ProtocolError} If interrogation fails
580
+ */
581
+ interrogate(): Promise<GlobalConfig>;
582
+ /**
583
+ * Read firmware version from device.
584
+ *
585
+ * @returns FirmwareVersion with major, minor, and sha fields
586
+ */
587
+ readFirmwareVersion(): Promise<FirmwareVersion>;
588
+ /**
589
+ * Reboot the device.
590
+ *
591
+ * Sends a reboot command to the device, which will cause an immediate
592
+ * system reset. The device will NOT send an ACK response - it simply
593
+ * resets after a 100ms delay.
594
+ *
595
+ * Warning: The BLE connection will be forcibly terminated when the device
596
+ * resets. This is expected behavior. The device will restart and begin
597
+ * advertising again after the reset completes (typically within a few seconds).
598
+ *
599
+ * @throws {BLEConnectionError} If command cannot be sent
600
+ */
601
+ reboot(): Promise<void>;
602
+ /**
603
+ * Write configuration to device.
604
+ *
605
+ * Serializes the GlobalConfig to TLV binary format and writes it
606
+ * to the device using the WRITE_CONFIG (0x0041) command with
607
+ * automatic chunking for large configs.
608
+ *
609
+ * @param config - GlobalConfig to write to device
610
+ * @throws {Error} If config serialization fails or exceeds size limit
611
+ * @throws {BLEConnectionError} If write fails
612
+ * @throws {ProtocolError} If device returns error response
613
+ *
614
+ * @example
615
+ * ```typescript
616
+ * // Read current config
617
+ * const config = device.config;
618
+ *
619
+ * // Modify config
620
+ * config.displays[0].rotation = 180;
621
+ *
622
+ * // Write back to device
623
+ * await device.writeConfig(config);
624
+ *
625
+ * // Reboot to apply changes
626
+ * await device.reboot();
627
+ * ```
628
+ */
629
+ writeConfig(config: GlobalConfig): Promise<void>;
630
+ /**
631
+ * Upload image to device display.
632
+ *
633
+ * Automatically handles:
634
+ * - Image resizing to display dimensions
635
+ * - Dithering based on color scheme
636
+ * - Encoding to device format
637
+ * - Compression
638
+ * - Direct write protocol
639
+ *
640
+ * @param imageData - Image as ImageData (from canvas or OffscreenCanvas)
641
+ * @param options - Upload options
642
+ * @throws {Error} If device not interrogated/configured
643
+ * @throws {ProtocolError} If upload fails
644
+ *
645
+ * @example
646
+ * ```typescript
647
+ * const canvas = document.getElementById('myCanvas') as HTMLCanvasElement;
648
+ * const ctx = canvas.getContext('2d')!;
649
+ * const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
650
+ *
651
+ * await device.uploadImage(imageData, {
652
+ * refreshMode: RefreshMode.FULL,
653
+ * ditherMode: DitherMode.BURKES,
654
+ * compress: true
655
+ * });
656
+ * ```
657
+ */
658
+ uploadImage(imageData: ImageData, options?: {
659
+ refreshMode?: RefreshMode;
660
+ ditherMode?: DitherMode;
661
+ compress?: boolean;
662
+ }): Promise<void>;
663
+ /**
664
+ * Execute image upload using compressed or uncompressed protocol.
665
+ */
666
+ private executeUpload;
667
+ /**
668
+ * Send image data chunks with ACK handling.
669
+ *
670
+ * Sends image data in chunks via 0x0071 DATA commands. Handles:
671
+ * - Timeout recovery when firmware starts display refresh
672
+ * - Auto-completion detection (firmware sends 0x0072 END early)
673
+ * - Progress logging
674
+ *
675
+ * @param imageData - Data to send in chunks
676
+ * @returns True if device auto-completed (sent 0x0072 END early), false if all chunks sent normally
677
+ * @throws {ProtocolError} If unexpected response received
678
+ * @throws {BLETimeoutError} If no response within timeout
679
+ */
680
+ private sendDataChunks;
681
+ /**
682
+ * Extract DeviceCapabilities from GlobalConfig.
683
+ */
684
+ private extractCapabilitiesFromConfig;
685
+ /**
686
+ * Ensure device capabilities are available.
687
+ */
688
+ private ensureCapabilities;
689
+ /**
690
+ * Ensure device is connected.
691
+ */
692
+ private ensureConnected;
693
+ }
694
+
695
+ /**
696
+ * BLE device discovery for OpenDisplay devices.
697
+ *
698
+ * Note: Web Bluetooth API does not provide general scanning like Python's Bleak.
699
+ * Instead, we use requestDevice() which shows a browser picker dialog.
700
+ */
701
+ /**
702
+ * Discover OpenDisplay BLE devices using browser picker.
703
+ *
704
+ * Shows the browser's device picker dialog filtered to OpenDisplay devices.
705
+ * User selects a device, and we return it for connection.
706
+ *
707
+ * @param namePrefix - Optional name prefix filter (e.g., "OpenDisplay")
708
+ * @returns Selected BluetoothDevice
709
+ * @throws {Error} If Web Bluetooth not supported or user cancels
710
+ *
711
+ * @example
712
+ * ```typescript
713
+ * const device = await discoverDevices();
714
+ * // or with name filter:
715
+ * const device = await discoverDevices('OpenDisplay');
716
+ * ```
717
+ */
718
+ declare function discoverDevices(namePrefix?: string): Promise<BluetoothDevice>;
719
+
720
+ /**
721
+ * BLE advertisement data structures.
722
+ */
723
+ /**
724
+ * Parsed BLE advertisement manufacturer data.
725
+ *
726
+ * Advertisement format (11 bytes, manufacturer ID already stripped by Web Bluetooth):
727
+ *
728
+ * - [0-6]: Fixed protocol bytes
729
+ * - [7-8]: Battery voltage in millivolts (little-endian uint16)
730
+ * - [9]: Chip temperature in Celsius (signed int8)
731
+ * - [10]: Loop counter (uint8, increments each advertisement)
732
+ *
733
+ * Note: Web Bluetooth provides manufacturer data without the manufacturer ID prefix.
734
+ */
735
+ interface AdvertisementData {
736
+ /** Battery voltage in millivolts */
737
+ batteryMv: number;
738
+ /** Chip temperature in Celsius */
739
+ temperatureC: number;
740
+ /** Incrementing counter for each advertisement */
741
+ loopCounter: number;
742
+ }
743
+ /**
744
+ * Parse BLE advertisement manufacturer data.
745
+ *
746
+ * Note: The manufacturer ID (0x2446) is already stripped by Web Bluetooth
747
+ * and provided as the key in manufacturerData.
748
+ *
749
+ * @param data - Raw manufacturer data (11 bytes, without the manufacturer ID prefix)
750
+ * @returns AdvertisementData with parsed values
751
+ * @throws {Error} If data is too short
752
+ */
753
+ declare function parseAdvertisement(data: Uint8Array): AdvertisementData;
754
+
755
+ /**
756
+ * Exception classes for OpenDisplay library.
757
+ */
758
+ declare class OpenDisplayError extends Error {
759
+ constructor(message: string);
760
+ }
761
+ declare class BLEConnectionError extends OpenDisplayError {
762
+ constructor(message: string);
763
+ }
764
+ declare class BLETimeoutError extends OpenDisplayError {
765
+ constructor(message: string);
766
+ }
767
+ declare class ProtocolError extends OpenDisplayError {
768
+ constructor(message: string);
769
+ }
770
+ declare class ConfigParseError extends ProtocolError {
771
+ constructor(message: string);
772
+ }
773
+ declare class InvalidResponseError extends ProtocolError {
774
+ constructor(message: string);
775
+ }
776
+ declare class ImageEncodingError extends OpenDisplayError {
777
+ constructor(message: string);
778
+ }
779
+
780
+ export { type AdvertisementData, BLEConnectionError, BLETimeoutError, BinaryInputs, BusType, ConfigParseError, DataBus, type DeviceCapabilities, DisplayConfig, type FirmwareVersion, type GlobalConfig, ICType, ImageEncodingError, InvalidResponseError, LedConfig, ManufacturerData, OpenDisplayDevice, OpenDisplayError, PowerMode, PowerOption, ProtocolError, RefreshMode, Rotation, SensorData, SystemConfig, discoverDevices, parseAdvertisement };