mirror of
https://github.com/YuzuZensai/beamboxctl.git
synced 2026-07-21 20:42:19 +00:00
✨ feat: Switch to noble fork
This commit is contained in:
+1
-2
@@ -22,7 +22,7 @@
|
|||||||
"author": "Yuzu <yuzu@kirameki.cafe>",
|
"author": "Yuzu <yuzu@kirameki.cafe>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@abandonware/noble": "^1.9.2-24",
|
"@stoprocent/noble": "^2.3.10",
|
||||||
"commander": "^14.0.3",
|
"commander": "^14.0.3",
|
||||||
"ink": "^6.6.0",
|
"ink": "^6.6.0",
|
||||||
"ink-big-text": "^2.0.0",
|
"ink-big-text": "^2.0.0",
|
||||||
@@ -32,7 +32,6 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^22.0.0",
|
"@types/node": "^22.0.0",
|
||||||
"@types/noble": "^0.0.44",
|
|
||||||
"@types/react": "^19.2.10",
|
"@types/react": "^19.2.10",
|
||||||
"tsup": "^8.3.5",
|
"tsup": "^8.3.5",
|
||||||
"tsx": "^4.19.2",
|
"tsx": "^4.19.2",
|
||||||
|
|||||||
Generated
+554
-983
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,8 @@
|
|||||||
|
ignoredBuiltDependencies:
|
||||||
|
- '@serialport/bindings-cpp'
|
||||||
|
- '@stoprocent/bluetooth-hci-socket'
|
||||||
|
- '@stoprocent/noble'
|
||||||
|
|
||||||
onlyBuiltDependencies:
|
onlyBuiltDependencies:
|
||||||
- '@abandonware/bluetooth-hci-socket'
|
- '@abandonware/bluetooth-hci-socket'
|
||||||
- '@abandonware/noble'
|
- '@abandonware/noble'
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { EventEmitter } from "node:events";
|
import { EventEmitter } from "node:events";
|
||||||
EventEmitter.defaultMaxListeners = 20;
|
EventEmitter.defaultMaxListeners = 20;
|
||||||
|
|
||||||
import noble from "@abandonware/noble";
|
import noble from "@stoprocent/noble";
|
||||||
import type { Peripheral, Characteristic } from "@abandonware/noble";
|
import type { Peripheral, Characteristic } from "@stoprocent/noble";
|
||||||
import type { BLEConfig, ProtocolConfig } from "../protocol/index.ts";
|
import type { BLEConfig, ProtocolConfig } from "../protocol/index.ts";
|
||||||
import { PacketType } from "../protocol/index.ts";
|
import { PacketType } from "../protocol/index.ts";
|
||||||
import { DeviceNotFoundError, ConnectionError } from "../utils/errors.ts";
|
import { DeviceNotFoundError, ConnectionError } from "../utils/errors.ts";
|
||||||
@@ -297,6 +297,12 @@ export class BleUploader {
|
|||||||
return match[1]; // Return short UUID part
|
return match[1]; // Return short UUID part
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For short UUIDs (3-4 hex chars), pad with zeros to 4 chars for consistent comparison
|
||||||
|
// This handles cases like "1f1" vs "01f1"
|
||||||
|
if (cleaned.length <= 4) {
|
||||||
|
return cleaned.padStart(4, "0");
|
||||||
|
}
|
||||||
|
|
||||||
return cleaned;
|
return cleaned;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,10 +431,34 @@ export class BleUploader {
|
|||||||
// Stop scanning before connecting
|
// Stop scanning before connecting
|
||||||
await noble.stopScanningAsync().catch(() => {});
|
await noble.stopScanningAsync().catch(() => {});
|
||||||
|
|
||||||
|
// Check peripheral state before connecting
|
||||||
|
logger.debug(
|
||||||
|
`Peripheral state before connect: ${this.peripheral!.state}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// If already connected, disconnect first to ensure clean state
|
||||||
|
if (
|
||||||
|
this.peripheral!.state === "connected" ||
|
||||||
|
this.peripheral!.state === "connecting"
|
||||||
|
) {
|
||||||
|
logger.debug(
|
||||||
|
"Device already connected/connecting, disconnecting first...",
|
||||||
|
);
|
||||||
|
await this.peripheral!.disconnectAsync().catch(() => {});
|
||||||
|
await this.sleep(500); // Brief delay after disconnect
|
||||||
|
}
|
||||||
|
|
||||||
// Connect to device
|
// Connect to device
|
||||||
logger.info("Connecting to device...", LogEventType.CONNECT_START);
|
logger.info("Connecting to device...", LogEventType.CONNECT_START);
|
||||||
|
const connectStartTime = Date.now();
|
||||||
|
|
||||||
await this.peripheral!.connectAsync();
|
await this.peripheral!.connectAsync();
|
||||||
logger.info("Connected to device", LogEventType.CONNECTED);
|
|
||||||
|
const connectDuration = Date.now() - connectStartTime;
|
||||||
|
logger.info(
|
||||||
|
`Connected to device (took ${connectDuration}ms)`,
|
||||||
|
LogEventType.CONNECTED,
|
||||||
|
);
|
||||||
|
|
||||||
// Handle disconnect events
|
// Handle disconnect events
|
||||||
this.peripheral!.once("disconnect", () => {
|
this.peripheral!.once("disconnect", () => {
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ export class BeamBoxUploader {
|
|||||||
private imageProcessor: ImageProcessor;
|
private imageProcessor: ImageProcessor;
|
||||||
private payloadBuilder: PayloadBuilder;
|
private payloadBuilder: PayloadBuilder;
|
||||||
private imageConfig: ImageConfig;
|
private imageConfig: ImageConfig;
|
||||||
|
private verbose: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
deviceAddress?: string,
|
deviceAddress?: string,
|
||||||
@@ -41,6 +42,7 @@ export class BeamBoxUploader {
|
|||||||
imageConfig?: ImageConfig,
|
imageConfig?: ImageConfig,
|
||||||
verbose: boolean = false,
|
verbose: boolean = false,
|
||||||
) {
|
) {
|
||||||
|
this.verbose = verbose;
|
||||||
this.imageConfig = imageConfig ?? DEFAULT_IMAGE_CONFIG;
|
this.imageConfig = imageConfig ?? DEFAULT_IMAGE_CONFIG;
|
||||||
this.ble = new BleUploader(
|
this.ble = new BleUploader(
|
||||||
deviceAddress ?? null,
|
deviceAddress ?? null,
|
||||||
@@ -315,20 +317,46 @@ export class BeamBoxUploader {
|
|||||||
// Wait for at least one status notification (PacketType.DEVICE_STATUS)
|
// Wait for at least one status notification (PacketType.DEVICE_STATUS)
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
const checkInterval = 100;
|
const checkInterval = 100;
|
||||||
|
let statusReceived = false;
|
||||||
|
let lastNotificationCount = 0;
|
||||||
|
|
||||||
while (Date.now() - startTime < timeoutMs) {
|
while (Date.now() - startTime < timeoutMs) {
|
||||||
const deviceStatus = this.ble.getDeviceStatus();
|
const deviceStatus = this.ble.getDeviceStatus();
|
||||||
|
const notifications = this.ble.getNotifications();
|
||||||
|
|
||||||
|
// Log progress if we got new notifications
|
||||||
|
if (notifications.length > lastNotificationCount) {
|
||||||
|
logger.debug(`Received ${notifications.length} total notifications so far...`);
|
||||||
|
lastNotificationCount = notifications.length;
|
||||||
|
}
|
||||||
|
|
||||||
if (deviceStatus && deviceStatus.type === 13) {
|
if (deviceStatus && deviceStatus.type === 13) {
|
||||||
logger.info(
|
logger.info(
|
||||||
`Device status received: ${JSON.stringify(deviceStatus)}`,
|
`Device status received: ${JSON.stringify(deviceStatus)}`,
|
||||||
);
|
);
|
||||||
logger.info("Device is ready for upload");
|
logger.info("Device is ready for upload");
|
||||||
|
statusReceived = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.sleep(checkInterval);
|
await this.sleep(checkInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!statusReceived) {
|
||||||
|
const notifications = this.ble.getNotifications();
|
||||||
|
logger.warning(
|
||||||
|
`Device status (type 13) not received within ${timeoutMs}ms timeout. Got ${notifications.length} notifications. Proceeding with available data.`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Log what we did receive if in verbose mode
|
||||||
|
if (notifications.length > 0 && this.verbose) {
|
||||||
|
logger.debug("Received notification types:");
|
||||||
|
notifications.forEach((n, i) => {
|
||||||
|
logger.debug(` [${i}] type: ${n.parsed?.jsonData?.type || 'unknown'}, data: ${JSON.stringify(n.parsed?.jsonData || {})}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const notifications = this.ble.getNotifications();
|
const notifications = this.ble.getNotifications();
|
||||||
|
|
||||||
logger.info(`Received ${notifications.length} notifications from device`);
|
logger.info(`Received ${notifications.length} notifications from device`);
|
||||||
|
|||||||
Reference in New Issue
Block a user